34 | 34 |
FwupdRelease *release;
|
35 | 35 |
GPtrArray *releases;
|
36 | 36 |
GfuMainMode mode;
|
37 | |
GDBusProxy *proxy;
|
38 | |
SoupSession *soup_session;
|
39 | 37 |
FwupdInstallFlags flags;
|
40 | 38 |
GfuOperation current_operation;
|
41 | 39 |
GTimer *time_elapsed;
|
42 | 40 |
gdouble last_estimate;
|
|
41 |
gchar *current_message;
|
43 | 42 |
} GfuMain;
|
44 | 43 |
|
45 | 44 |
/* used to compare rows in a list */
|
|
82 | 81 |
}
|
83 | 82 |
gtk_dialog_run (GTK_DIALOG (dialog));
|
84 | 83 |
gtk_widget_destroy (dialog);
|
|
84 |
}
|
|
85 |
|
|
86 |
static void
|
|
87 |
gfu_main_error_fatal (GfuMain *self, const gchar *text)
|
|
88 |
{
|
|
89 |
GtkWidget *w = GTK_WIDGET (gtk_builder_get_object (self->builder, "stack_main"));
|
|
90 |
gtk_stack_set_visible_child_name (GTK_STACK (w), "error");
|
|
91 |
w = GTK_WIDGET (gtk_builder_get_object (self->builder, "label_error"));
|
|
92 |
gtk_label_set_label (GTK_LABEL (w), text);
|
85 | 93 |
}
|
86 | 94 |
|
87 | 95 |
static void
|
|
208 | 216 |
/* set device information */
|
209 | 217 |
if (self->device != NULL) {
|
210 | 218 |
GPtrArray *guids;
|
|
219 |
GPtrArray *vendor_ids = fwupd_device_get_vendor_ids (self->device);
|
211 | 220 |
g_autoptr(GString) attr = g_string_new (NULL);
|
|
221 |
g_autoptr(GString) version = g_string_new (fwupd_device_get_version (self->device));
|
212 | 222 |
g_autoptr(GError) error = NULL;
|
213 | |
gchar *tmp;
|
214 | |
gchar *tmp2;
|
215 | |
|
216 | |
gfu_main_set_label (self, "label_device_version",
|
217 | |
fwupd_device_get_version (self->device));
|
|
223 |
const gchar *tmp;
|
|
224 |
|
|
225 |
#if FWUPD_CHECK_VERSION(1,6,2)
|
|
226 |
if (fwupd_device_get_version_build_date (self->device) != 0) {
|
|
227 |
guint64 value = fwupd_device_get_version_build_date (self->device);
|
|
228 |
g_autoptr(GDateTime) date = g_date_time_new_from_unix_utc ((gint64) value);
|
|
229 |
g_autofree gchar *datestr = g_date_time_format (date, "%F");
|
|
230 |
g_string_append_printf (version, " [%s]", datestr);
|
|
231 |
}
|
|
232 |
#endif
|
|
233 |
|
|
234 |
gfu_main_set_label (self, "label_device_version", version->str);
|
218 | 235 |
gfu_main_set_label (self, "label_device_version_lowest",
|
219 | 236 |
fwupd_device_get_version_lowest (self->device));
|
220 | 237 |
gfu_main_set_label (self, "label_device_version_bootloader",
|
|
225 | 242 |
fwupd_device_get_serial (self->device));
|
226 | 243 |
|
227 | 244 |
tmp = fwupd_device_get_vendor (self->device);
|
228 | |
tmp2 = fwupd_device_get_vendor_id (self->device);
|
229 | |
if (tmp != NULL && tmp2 != NULL) {
|
230 | |
g_autofree gchar *both = g_strdup_printf ("%s (%s)", tmp, tmp2);
|
|
245 |
if (tmp != NULL && vendor_ids->len > 0) {
|
|
246 |
g_autofree gchar *strv = gfu_common_strjoin_array (", ", vendor_ids);
|
|
247 |
g_autofree gchar *both = g_strdup_printf ("%s (%s)", tmp, strv);
|
231 | 248 |
gfu_main_set_label (self, "label_device_vendor", both);
|
232 | 249 |
} else if (tmp != NULL) {
|
233 | 250 |
gfu_main_set_label (self, "label_device_vendor", tmp);
|
234 | |
} else if (tmp2 != NULL) {
|
235 | |
gfu_main_set_label (self, "label_device_vendor", tmp2);
|
|
251 |
} else if (vendor_ids->len > 0) {
|
|
252 |
g_autofree gchar *strv = gfu_common_strjoin_array (", ", vendor_ids);
|
|
253 |
gfu_main_set_label (self, "label_device_vendor", strv);
|
236 | 254 |
} else {
|
237 | 255 |
gfu_main_set_label (self, "label_device_vendor", NULL);
|
238 | 256 |
}
|
|
243 | 261 |
|
244 | 262 |
gfu_main_set_label (self, "label_device_install_duration",
|
245 | 263 |
gfu_common_seconds_to_string (fwupd_device_get_install_duration (self->device)));
|
246 | |
|
247 | 264 |
|
248 | 265 |
gfu_main_set_device_flags (self, fwupd_device_get_flags (self->device));
|
249 | 266 |
|
|
260 | 277 |
/* set GUIDs->GUID if only one */
|
261 | 278 |
gfu_main_set_label_title (self, "label_device_guids", ngettext ("GUID", "GUIDs", guids->len));
|
262 | 279 |
|
263 | |
#if FWUPD_CHECK_VERSION(1,3,3)
|
264 | 280 |
/* device can be verified immediately without a round trip to firmware */
|
265 | 281 |
if (fwupd_device_has_flag (self->device, FWUPD_DEVICE_FLAG_CAN_VERIFY) &&
|
266 | 282 |
!fwupd_device_has_flag (self->device, FWUPD_DEVICE_FLAG_CAN_VERIFY_IMAGE)) {
|
|
283 |
//FIXME async
|
267 | 284 |
if (!fwupd_client_verify (self->client,
|
268 | |
fwupd_device_get_id (self->device),
|
269 | |
self->cancellable,
|
270 | |
&error)) {
|
|
285 |
fwupd_device_get_id (self->device),
|
|
286 |
self->cancellable,
|
|
287 |
&error)) {
|
271 | 288 |
gfu_main_set_label (self, "label_device_checksums", error->message);
|
272 | 289 |
} else {
|
273 | 290 |
gfu_main_set_label (self, "label_device_checksums", _("Cryptographic hashes match"));
|
|
281 | 298 |
} else {
|
282 | 299 |
gfu_main_set_label (self, "label_device_checksums", NULL);
|
283 | 300 |
}
|
284 | |
#else
|
285 | |
gfu_main_set_label (self, "label_device_checksums", NULL);
|
286 | |
#endif
|
|
301 |
|
287 | 302 |
//fixme: get parents
|
288 | 303 |
//FwupdDevice *parent = fwupd_device_get_parent (self->device);
|
289 | 304 |
//g_print ("parent: %s\n", fwupd_device_get_name (parent));
|
|
334 | 349 |
ngettext ("Checksum", "Checksums", checks->len));
|
335 | 350 |
}
|
336 | 351 |
|
337 | |
#if FWUPD_CHECK_VERSION(1,3,2)
|
338 | 352 |
issues = fwupd_release_get_issues (self->release);
|
339 | |
#endif
|
340 | |
if (issues == NULL || issues->len == 0) {
|
|
353 |
if (issues->len == 0) {
|
341 | 354 |
gfu_main_set_label (self, "label_release_issues", NULL);
|
342 | 355 |
} else {
|
343 | 356 |
g_autoptr(GString) str = g_string_new (NULL);
|
|
425 | 438 |
|
426 | 439 |
/* verify button */
|
427 | 440 |
w = GTK_WIDGET (gtk_builder_get_object (self->builder, "button_verify"));
|
428 | |
#if FWUPD_CHECK_VERSION(1,3,3)
|
429 | 441 |
gtk_widget_set_visible (w, self->device != NULL &&
|
430 | 442 |
!verification_matched &&
|
431 | 443 |
fwupd_device_has_flag (self->device, FWUPD_DEVICE_FLAG_CAN_VERIFY_IMAGE));
|
432 | |
#else
|
433 | |
gtk_widget_set_visible (w, verification_matched);
|
434 | |
#endif
|
435 | 444 |
|
436 | 445 |
/* verify update button */
|
437 | 446 |
w = GTK_WIDGET (gtk_builder_get_object (self->builder, "button_verify_update"));
|
438 | |
#if FWUPD_CHECK_VERSION(1,3,3)
|
439 | 447 |
gtk_widget_set_visible (w, self->device != NULL &&
|
440 | 448 |
!verification_matched &&
|
441 | 449 |
fwupd_device_has_flag (self->device, FWUPD_DEVICE_FLAG_CAN_VERIFY));
|
442 | |
#else
|
443 | |
gtk_widget_set_visible (w, verification_matched);
|
444 | |
#endif
|
|
450 |
|
445 | 451 |
/* releases button */
|
446 | 452 |
w = GTK_WIDGET (gtk_builder_get_object (self->builder, "button_releases"));
|
447 | 453 |
if (self->releases == NULL || self->releases->len == 0) {
|
|
468 | 474 |
w = GTK_WIDGET (gtk_builder_get_object (self->builder, "listbox_main"));
|
469 | 475 |
|
470 | 476 |
/* ignore if device can't be updated */
|
471 | |
if (!fwupd_device_has_flag (device, FWUPD_DEVICE_FLAG_UPDATABLE))
|
472 | |
return;
|
|
477 |
if (!fwupd_device_has_flag (device, FWUPD_DEVICE_FLAG_UPDATABLE) &&
|
|
478 |
!fwupd_device_has_flag (device, FWUPD_DEVICE_FLAG_UPDATABLE_HIDDEN))
|
|
479 |
return;
|
|
480 |
|
473 | 481 |
/* create and add new row for device */
|
474 | 482 |
l = gfu_device_row_new (device);
|
475 | 483 |
gtk_widget_set_visible (l, TRUE);
|
|
521 | 529 |
gfu_main_reboot_shutdown_prompt (GfuMain *self)
|
522 | 530 |
{
|
523 | 531 |
g_autoptr(GError) error = NULL;
|
524 | |
guint64 flags = fwupd_device_get_flags (self->device);
|
525 | 532 |
|
526 | 533 |
/* if successful, prompt for reboot */
|
527 | 534 |
// FIXME: handle with device::changed instead of removing
|
528 | 535 |
|
529 | |
if (flags & FWUPD_DEVICE_FLAG_NEEDS_SHUTDOWN) {
|
|
536 |
if (fwupd_device_has_flag (self->device, FWUPD_DEVICE_FLAG_NEEDS_SHUTDOWN)) {
|
530 | 537 |
/* shutdown prompt */
|
531 | 538 |
GtkWindow *window;
|
532 | 539 |
GtkWidget *dialog;
|
|
569 | 576 |
|
570 | 577 |
gtk_widget_destroy (dialog);
|
571 | 578 |
}
|
572 | |
if (flags & FWUPD_DEVICE_FLAG_NEEDS_REBOOT) {
|
|
579 |
if (fwupd_device_has_flag (self->device, FWUPD_DEVICE_FLAG_NEEDS_REBOOT)) {
|
573 | 580 |
/* shutdown prompt */
|
574 | 581 |
GtkWindow *window;
|
575 | 582 |
GtkWidget *dialog;
|
|
625 | 632 |
/* async getter functions */
|
626 | 633 |
|
627 | 634 |
static void
|
628 | |
gfu_main_update_remotes_cb (GObject *source_object, GAsyncResult *res, gpointer user_data)
|
|
635 |
gfu_main_update_remotes_cb (GObject *source, GAsyncResult *res, gpointer user_data)
|
629 | 636 |
{
|
630 | 637 |
GfuMain *self = (GfuMain *) user_data;
|
631 | 638 |
GtkWidget *w;
|
632 | 639 |
gboolean disabled_lvfs_remote = FALSE;
|
633 | 640 |
gboolean enabled_any_download_remote = FALSE;
|
634 | 641 |
g_autoptr(GError) error = NULL;
|
635 | |
g_autoptr(GVariant) val = g_dbus_proxy_call_finish (self->proxy, res, &error);
|
636 | 642 |
g_autoptr(GPtrArray) remotes = NULL;
|
637 | 643 |
|
638 | |
if (val == NULL) {
|
|
644 |
remotes = fwupd_client_get_remotes_finish (FWUPD_CLIENT (source), res, &error);
|
|
645 |
if (remotes == NULL) {
|
639 | 646 |
gfu_main_error_dialog (self, _("Failed to load list of remotes"), error->message);
|
640 | 647 |
return;
|
641 | 648 |
}
|
642 | |
remotes = fwupd_remote_array_from_variant (val);
|
643 | 649 |
for (guint i = 0; i < remotes->len; i++) {
|
644 | 650 |
FwupdRemote *remote = g_ptr_array_index (remotes, i);
|
645 | 651 |
g_debug ("%s is %s", fwupd_remote_get_id (remote),
|
|
658 | 664 |
}
|
659 | 665 |
|
660 | 666 |
w = GTK_WIDGET (gtk_builder_get_object (self->builder, "infobar_enable_lvfs"));
|
661 | |
gtk_info_bar_set_revealed (GTK_INFO_BAR (w),
|
662 | |
disabled_lvfs_remote && !enabled_any_download_remote);
|
663 | |
}
|
664 | |
|
665 | |
static void
|
666 | |
gfu_main_update_devices_cb (GObject *source_object, GAsyncResult *res, gpointer user_data)
|
|
667 |
if (disabled_lvfs_remote && !enabled_any_download_remote) {
|
|
668 |
gtk_widget_set_visible (w, TRUE);
|
|
669 |
gtk_info_bar_set_revealed (GTK_INFO_BAR (w), TRUE);
|
|
670 |
} else {
|
|
671 |
gtk_widget_set_visible (w, FALSE);
|
|
672 |
}
|
|
673 |
}
|
|
674 |
|
|
675 |
static void
|
|
676 |
gfu_main_update_devices_cb (GObject *source, GAsyncResult *res, gpointer user_data)
|
667 | 677 |
{
|
668 | 678 |
GtkWidget *w;
|
669 | 679 |
GtkWidget *l = NULL;
|
670 | 680 |
GfuMain *self = (GfuMain *) user_data;
|
671 | 681 |
g_autoptr(GError) error = NULL;
|
672 | 682 |
g_autoptr(GPtrArray) devices = NULL;
|
673 | |
g_autoptr(GVariant) tmp = g_dbus_proxy_call_finish (self->proxy, res, &error);
|
674 | |
|
675 | |
if (tmp == NULL) {
|
|
683 |
|
|
684 |
devices = fwupd_client_get_devices_finish (FWUPD_CLIENT (source), res, &error);
|
|
685 |
if (devices == NULL) {
|
676 | 686 |
gfu_main_error_dialog (self, _("Failed to load device list"), error->message);
|
677 | 687 |
return;
|
678 | 688 |
}
|
679 | |
|
680 | |
devices = fwupd_device_array_from_variant (tmp);
|
681 | 689 |
|
682 | 690 |
/* create a row in the listbox for each updatable device */
|
683 | 691 |
w = GTK_WIDGET (gtk_builder_get_object (self->builder, "listbox_main"));
|
|
685 | 693 |
FwupdDevice *device = g_ptr_array_index (devices, i);
|
686 | 694 |
/* skip devices that can't be updated */
|
687 | 695 |
if (!fwupd_device_has_flag (device, FWUPD_DEVICE_FLAG_UPDATABLE) &&
|
|
696 |
!fwupd_device_has_flag (device, FWUPD_DEVICE_FLAG_UPDATABLE_HIDDEN) &&
|
688 | 697 |
!fwupd_device_has_flag (device, FWUPD_DEVICE_FLAG_LOCKED)) {
|
689 | 698 |
g_debug ("ignoring non-updatable device: %s", fwupd_device_get_name (device));
|
690 | 699 |
continue;
|
|
702 | 711 |
}
|
703 | 712 |
|
704 | 713 |
static void
|
705 | |
gfu_main_update_releases_cb (GObject *source_object, GAsyncResult *res, gpointer user_data)
|
|
714 |
gfu_main_update_releases_cb (GObject *source, GAsyncResult *res, gpointer user_data)
|
706 | 715 |
{
|
707 | 716 |
GtkWidget *w;
|
708 | 717 |
GfuMain *self = (GfuMain *) user_data;
|
709 | 718 |
g_autoptr(GError) error = NULL;
|
710 | |
g_autoptr(GVariant) tmp = g_dbus_proxy_call_finish (self->proxy, res, &error);
|
711 | |
if (tmp == NULL) {
|
|
719 |
|
|
720 |
self->releases = fwupd_client_get_releases_finish (FWUPD_CLIENT(source), res, &error);
|
|
721 |
if (self->releases == NULL) {
|
712 | 722 |
/* No firmware found for this devices */
|
713 | 723 |
g_debug ("ignoring: %s", error->message);
|
714 | 724 |
return;
|
715 | 725 |
}
|
716 | |
self->releases = fwupd_release_array_from_variant (tmp);
|
717 | 726 |
|
718 | 727 |
w = GTK_WIDGET (gtk_builder_get_object (self->builder, "listbox_firmware"));
|
719 | 728 |
gfu_main_container_remove_all (GTK_CONTAINER (w));
|
|
764 | 773 |
}
|
765 | 774 |
|
766 | 775 |
static void
|
767 | |
gfu_main_download_chunk_cb (SoupMessage *msg, SoupBuffer *chunk, gpointer user_data)
|
768 | |
{
|
769 | |
guint percentage;
|
770 | |
goffset header_size;
|
771 | |
goffset body_length;
|
|
776 |
gfu_main_client_percentage_changed_cb (FwupdClient *client, GParamSpec *pspec, GfuMain *self)
|
|
777 |
{
|
|
778 |
g_autofree gchar *str = NULL;
|
|
779 |
g_debug ("progress: %u%%", fwupd_client_get_percentage (client));
|
|
780 |
str = g_strdup_printf ("%s (%u%%)", _("Downloading"),
|
|
781 |
fwupd_client_get_percentage (client));
|
|
782 |
gfu_main_set_install_loading_label (self, str);
|
|
783 |
}
|
|
784 |
|
|
785 |
static void
|
|
786 |
gfu_main_refresh_remote_cb (GObject *source, GAsyncResult *res, gpointer user_data)
|
|
787 |
{
|
772 | 788 |
GfuMain *self = (GfuMain *) user_data;
|
773 | |
|
774 | |
/* if it's returning "Found" or an error, ignore the percentage */
|
775 | |
if (msg->status_code != SOUP_STATUS_OK) {
|
776 | |
g_debug ("ignoring status code %u (%s)",
|
777 | |
msg->status_code, msg->reason_phrase);
|
778 | |
return;
|
779 | |
}
|
780 | |
|
781 | |
/* get data */
|
782 | |
body_length = msg->response_body->length;
|
783 | |
header_size = soup_message_headers_get_content_length (msg->response_headers);
|
784 | |
|
785 | |
/* size is not known */
|
786 | |
if (header_size < body_length)
|
787 | |
return;
|
788 | |
|
789 | |
/* calculate percentage */
|
790 | |
percentage = (guint) ((100 * body_length) / header_size);
|
791 | |
g_debug ("progress: %u%%", percentage);
|
792 | |
gfu_main_set_install_loading_label (self, g_strdup_printf ("%s (%u%%)",
|
793 | |
_("Downloading"),
|
794 | |
percentage));
|
795 | |
}
|
796 | |
|
797 | |
static gboolean
|
798 | |
gfu_main_download_file (GfuMain *self,
|
799 | |
SoupURI *uri,
|
800 | |
const gchar *fn,
|
801 | |
const gchar *checksum_expected,
|
802 | |
GError **error)
|
803 | |
{
|
804 | |
GChecksumType checksum_type;
|
805 | |
guint status_code;
|
806 | |
g_autoptr(GError) error_local = NULL;
|
807 | |
g_autofree gchar *checksum_actual = NULL;
|
808 | |
g_autofree gchar *uri_str = NULL;
|
809 | |
g_autoptr(SoupMessage) msg = NULL;
|
810 | |
|
811 | |
/* check if the file already exists with the right checksum */
|
812 | |
checksum_type = fwupd_checksum_guess_kind (checksum_expected);
|
813 | |
if (gfu_common_file_exists_with_checksum (fn, checksum_expected, checksum_type)) {
|
814 | |
g_debug ("skipping download as file already exists");
|
815 | |
gfu_main_set_install_loading_label (self, _("File already downloaded..."));
|
816 | |
return TRUE;
|
817 | |
}
|
818 | |
|
819 | |
/* set up networking */
|
820 | |
if (self->soup_session == NULL) {
|
821 | |
self->soup_session = gfu_common_setup_networking (error);
|
822 | |
if (self->soup_session == NULL)
|
823 | |
return FALSE;
|
824 | |
}
|
825 | |
|
826 | |
/* download data */
|
827 | |
uri_str = soup_uri_to_string (uri, FALSE);
|
828 | |
g_debug ("downloading %s to %s", uri_str, fn);
|
829 | |
gfu_main_set_install_loading_label (self, _("Downloading file..."));
|
830 | |
msg = soup_message_new_from_uri (SOUP_METHOD_GET, uri);
|
831 | |
if (msg == NULL) {
|
832 | |
g_set_error (error,
|
833 | |
FWUPD_ERROR,
|
834 | |
FWUPD_ERROR_INVALID_FILE,
|
835 | |
"Failed to parse URI %s", uri_str);
|
836 | |
return FALSE;
|
837 | |
}
|
838 | |
if (g_str_has_suffix (uri_str, ".asc") ||
|
839 | |
g_str_has_suffix (uri_str, ".p7b") ||
|
840 | |
g_str_has_suffix (uri_str, ".p7c")) {
|
841 | |
/* TRANSLATORS: downloading new signing file */
|
842 | |
g_debug ("%s %s\n", _("Fetching signature"), uri_str);
|
843 | |
gfu_main_set_install_loading_label (self, _("Fetching signature..."));
|
844 | |
} else if (g_str_has_suffix (uri_str, ".gz")) {
|
845 | |
/* TRANSLATORS: downloading new metadata file */
|
846 | |
g_debug ("%s %s\n", _("Fetching metadata"), uri_str);
|
847 | |
gfu_main_set_install_loading_label (self, _("Fetching metadata..."));
|
848 | |
} else if (g_str_has_suffix (uri_str, ".cab")) {
|
849 | |
/* TRANSLATORS: downloading new firmware file */
|
850 | |
g_debug ("%s %s\n", _("Fetching firmware"), uri_str);
|
851 | |
gfu_main_set_install_loading_label (self, _("Fetching firmware..."));
|
852 | |
} else {
|
853 | |
/* TRANSLATORS: downloading unknown file */
|
854 | |
g_debug ("%s %s\n", _("Fetching file"), uri_str);
|
855 | |
gfu_main_set_install_loading_label (self, _("Fetching file..."));
|
856 | |
}
|
857 | |
g_signal_connect (msg, "got-chunk",
|
858 | |
G_CALLBACK (gfu_main_download_chunk_cb), self);
|
859 | |
status_code = soup_session_send_message (self->soup_session, msg);
|
860 | |
g_debug ("\n");
|
861 | |
if (status_code == 429) {
|
862 | |
g_autofree gchar *str = g_strndup (msg->response_body->data,
|
863 | |
msg->response_body->length);
|
864 | |
if (g_strcmp0 (str, "Too Many Requests") == 0) {
|
865 | |
g_set_error (error,
|
866 | |
FWUPD_ERROR,
|
867 | |
FWUPD_ERROR_INVALID_FILE,
|
868 | |
/* TRANSLATORS: the server is rate-limiting downloads */
|
869 | |
"%s", _("Failed to download due to server limit"));
|
870 | |
return FALSE;
|
871 | |
}
|
872 | |
g_set_error (error,
|
873 | |
FWUPD_ERROR,
|
874 | |
FWUPD_ERROR_INVALID_FILE,
|
875 | |
_("Failed to download due to server limit: %s"), str);
|
876 | |
return FALSE;
|
877 | |
}
|
878 | |
if (status_code != SOUP_STATUS_OK) {
|
879 | |
g_set_error (error,
|
880 | |
FWUPD_ERROR,
|
881 | |
FWUPD_ERROR_INVALID_FILE,
|
882 | |
_("Failed to download %s: %s"),
|
883 | |
uri_str, soup_status_get_phrase (status_code));
|
884 | |
return FALSE;
|
885 | |
}
|
886 | |
|
887 | |
/* verify checksum */
|
888 | |
if (checksum_expected != NULL) {
|
889 | |
checksum_actual = g_compute_checksum_for_data (checksum_type,
|
890 | |
(guchar *) msg->response_body->data,
|
891 | |
(gsize) msg->response_body->length);
|
892 | |
if (g_strcmp0 (checksum_expected, checksum_actual) != 0) {
|
893 | |
g_set_error (error,
|
894 | |
FWUPD_ERROR,
|
895 | |
FWUPD_ERROR_INVALID_FILE,
|
896 | |
_("Checksum invalid, expected %s got %s"),
|
897 | |
checksum_expected, checksum_actual);
|
898 | |
return FALSE;
|
899 | |
}
|
900 | |
}
|
901 | |
|
902 | |
/* save file */
|
903 | |
if (!g_file_set_contents (fn,
|
904 | |
msg->response_body->data,
|
905 | |
msg->response_body->length,
|
906 | |
&error_local)) {
|
907 | |
g_set_error (error,
|
908 | |
FWUPD_ERROR,
|
909 | |
FWUPD_ERROR_WRITE,
|
910 | |
_("Failed to save file: %s"),
|
911 | |
error_local->message);
|
912 | |
return FALSE;
|
913 | |
}
|
914 | |
return TRUE;
|
915 | |
}
|
916 | |
|
917 | |
static gboolean
|
918 | |
gfu_main_download_metadata_for_remote (GfuMain *self,
|
919 | |
FwupdRemote *remote,
|
920 | |
GError **error)
|
921 | |
{
|
922 | |
g_autofree gchar *basename_asc = NULL;
|
923 | |
g_autofree gchar *basename_id_asc = NULL;
|
924 | |
g_autofree gchar *basename_id = NULL;
|
925 | |
g_autofree gchar *basename = NULL;
|
926 | |
g_autofree gchar *filename = NULL;
|
927 | |
g_autofree gchar *filename_asc = NULL;
|
928 | |
g_autoptr(SoupURI) uri = NULL;
|
929 | |
g_autoptr(SoupURI) uri_sig = NULL;
|
930 | |
|
931 | |
/* generate some plausible local filenames */
|
932 | |
basename = g_path_get_basename (fwupd_remote_get_filename_cache (remote));
|
933 | |
basename_id = g_strdup_printf ("%s-%s", fwupd_remote_get_id (remote), basename);
|
934 | |
|
935 | |
/* download the metadata */
|
936 | |
filename = gfu_get_user_cache_path (basename_id);
|
937 | |
gfu_main_set_install_loading_label (self, _("Creating cache path..."));
|
938 | |
if (!gfu_common_mkdir_parent (filename, error))
|
939 | |
return FALSE;
|
940 | |
uri = soup_uri_new (fwupd_remote_get_metadata_uri (remote));
|
941 | |
gfu_main_set_install_loading_label (self, _("Preparing to download file..."));
|
942 | |
if (!gfu_main_download_file (self, uri, filename, NULL, error))
|
943 | |
return FALSE;
|
944 | |
|
945 | |
/* download the signature */
|
946 | |
basename_asc = g_path_get_basename (fwupd_remote_get_filename_cache_sig (remote));
|
947 | |
basename_id_asc = g_strdup_printf ("%s-%s", fwupd_remote_get_id (remote), basename_asc);
|
948 | |
filename_asc = gfu_get_user_cache_path (basename_id_asc);
|
949 | |
uri_sig = soup_uri_new (fwupd_remote_get_metadata_uri_sig (remote));
|
950 | |
gfu_main_set_install_loading_label (self, _("Preparing to download file..."));
|
951 | |
if (!gfu_main_download_file (self, uri_sig, filename_asc, NULL, error))
|
952 | |
return FALSE;
|
953 | |
|
954 | |
/* send all this to fwupd */
|
955 | |
return fwupd_client_update_metadata (self->client,
|
956 | |
fwupd_remote_get_id (remote),
|
957 | |
filename,
|
958 | |
filename_asc,
|
959 | |
NULL, error);
|
|
789 |
g_autoptr(GError) error = NULL;
|
|
790 |
|
|
791 |
if (!fwupd_client_update_metadata_bytes_finish (FWUPD_CLIENT (source), res, &error)) {
|
|
792 |
gfu_main_error_dialog (self, _("Failed to refresh metadata"), error->message);
|
|
793 |
return;
|
|
794 |
}
|
|
795 |
gfu_main_show_install_loading (self, FALSE);
|
|
796 |
}
|
|
797 |
|
|
798 |
static void
|
|
799 |
gfu_main_get_lvfs_remote_cb (GObject *source, GAsyncResult *res, gpointer user_data)
|
|
800 |
{
|
|
801 |
GfuMain *self = (GfuMain *) user_data;
|
|
802 |
g_autoptr(FwupdRemote) remote = NULL;
|
|
803 |
g_autoptr(GError) error = NULL;
|
|
804 |
|
|
805 |
remote = fwupd_client_get_remote_by_id_finish (FWUPD_CLIENT (source), res, &error);
|
|
806 |
if (remote == NULL) {
|
|
807 |
gfu_main_error_dialog (self, _("Failed to find LVFS"), error->message);
|
|
808 |
gfu_main_show_install_loading (self, FALSE);
|
|
809 |
return;
|
|
810 |
}
|
|
811 |
|
|
812 |
gfu_main_set_install_loading_label (self, _("Refreshing remote..."));
|
|
813 |
fwupd_client_refresh_remote_async (self->client, remote,
|
|
814 |
self->cancellable,
|
|
815 |
gfu_main_refresh_remote_cb,
|
|
816 |
self);
|
|
817 |
}
|
|
818 |
|
|
819 |
static void
|
|
820 |
gfu_main_modify_remote_cb (GObject *source, GAsyncResult *res, gpointer user_data)
|
|
821 |
{
|
|
822 |
GfuMain *self = (GfuMain *) user_data;
|
|
823 |
g_autoptr(GError) error = NULL;
|
|
824 |
|
|
825 |
if (!fwupd_client_modify_remote_finish (FWUPD_CLIENT (source), res, &error)) {
|
|
826 |
gfu_main_error_dialog (self, _("Failed to enable LVFS"), error->message);
|
|
827 |
gfu_main_show_install_loading (self, FALSE);
|
|
828 |
return;
|
|
829 |
}
|
|
830 |
|
|
831 |
/* refresh the newly-enabled remote */
|
|
832 |
fwupd_client_get_remote_by_id_async (self->client, "lvfs", self->cancellable,
|
|
833 |
gfu_main_get_lvfs_remote_cb,
|
|
834 |
self);
|
960 | 835 |
}
|
961 | 836 |
|
962 | 837 |
static void
|
963 | 838 |
gfu_main_enable_lvfs_cb (GtkWidget *widget, GfuMain *self)
|
964 | 839 |
{
|
965 | 840 |
GtkWidget *w;
|
966 | |
g_autoptr(FwupdRemote) remote = NULL;
|
967 | |
g_autoptr(GError) error = NULL;
|
968 | 841 |
|
969 | 842 |
/* hide notification */
|
970 | 843 |
w = GTK_WIDGET (gtk_builder_get_object (self->builder, "infobar_enable_lvfs"));
|
|
972 | 845 |
|
973 | 846 |
/* enable remote */
|
974 | 847 |
gfu_main_show_install_loading (self, TRUE);
|
975 | |
if (!fwupd_client_modify_remote (self->client, "lvfs", "Enabled", "true", NULL, &error)) {
|
976 | |
gfu_main_error_dialog (self, _("Failed to enable LVFS"), error->message);
|
|
848 |
fwupd_client_modify_remote_async (self->client, "lvfs", "Enabled", "true",
|
|
849 |
self->cancellable,
|
|
850 |
gfu_main_modify_remote_cb,
|
|
851 |
self);
|
|
852 |
}
|
|
853 |
|
|
854 |
static void
|
|
855 |
gfu_main_get_remotes_cb (GObject *source, GAsyncResult *res, gpointer user_data)
|
|
856 |
{
|
|
857 |
GfuMain *self = (GfuMain *) user_data;
|
|
858 |
g_autoptr(GError) error = NULL;
|
|
859 |
g_autoptr(GPtrArray) remotes = NULL;
|
|
860 |
|
|
861 |
remotes = fwupd_client_get_remotes_finish (FWUPD_CLIENT (source), res, &error);
|
|
862 |
if (remotes == NULL) {
|
|
863 |
gfu_main_error_dialog (self, _("Failed to get remotes list"), error->message);
|
977 | 864 |
gfu_main_show_install_loading (self, FALSE);
|
978 | 865 |
return;
|
979 | |
}
|
980 | |
|
981 | |
/* refresh the newly-enabled remote */
|
982 | |
remote = fwupd_client_get_remote_by_id (self->client, "lvfs", NULL, &error);
|
983 | |
if (remote == NULL) {
|
984 | |
gfu_main_error_dialog (self, _("Failed to find LVFS"), error->message);
|
985 | |
gfu_main_show_install_loading (self, FALSE);
|
986 | |
return;
|
987 | |
}
|
988 | |
if (!gfu_main_download_metadata_for_remote (self, remote, &error)) {
|
989 | |
gfu_main_error_dialog (self, _("Failed to download metadata for LVFS"), error->message);
|
990 | |
gfu_main_show_install_loading (self, FALSE);
|
991 | |
return;
|
992 | |
}
|
993 | |
gfu_main_show_install_loading (self, FALSE);
|
994 | |
}
|
995 | |
|
996 | |
static gboolean
|
997 | |
gfu_main_download_metadata (GfuMain *self, GError **error)
|
998 | |
{
|
999 | |
g_autoptr(GPtrArray) remotes = NULL;
|
1000 | |
|
1001 | |
/* begin downloading, show loading animation */
|
1002 | |
gfu_main_show_install_loading (self, TRUE);
|
1003 | |
|
1004 | |
remotes = fwupd_client_get_remotes (self->client, NULL, error);
|
1005 | |
if (remotes == NULL) {
|
1006 | |
gfu_main_show_install_loading (self, FALSE);
|
1007 | |
return FALSE;
|
1008 | 866 |
}
|
1009 | 867 |
for (guint i = 0; i < remotes->len; i++) {
|
1010 | 868 |
FwupdRemote *remote = g_ptr_array_index (remotes, i);
|
|
1012 | 870 |
continue;
|
1013 | 871 |
if (fwupd_remote_get_kind (remote) != FWUPD_REMOTE_KIND_DOWNLOAD)
|
1014 | 872 |
continue;
|
1015 | |
if (!gfu_main_download_metadata_for_remote (self, remote, error)) {
|
1016 | |
gfu_main_show_install_loading (self, FALSE);
|
1017 | |
return FALSE;
|
1018 | |
}
|
|
873 |
/* should this be a single async action? */
|
|
874 |
fwupd_client_refresh_remote_async (self->client, remote,
|
|
875 |
self->cancellable,
|
|
876 |
gfu_main_refresh_remote_cb,
|
|
877 |
self);
|
1019 | 878 |
}
|
1020 | 879 |
|
1021 | 880 |
gfu_main_show_install_loading (self, FALSE);
|
1022 | |
return TRUE;
|
1023 | 881 |
}
|
1024 | 882 |
|
1025 | 883 |
static void
|
1026 | 884 |
gfu_main_activate_refresh_metadata (GSimpleAction *simple, GVariant *parameter, gpointer user_data)
|
1027 | 885 |
{
|
1028 | 886 |
GfuMain *self = (GfuMain *) user_data;
|
1029 | |
g_autoptr(GError) error = NULL;
|
1030 | |
if (!gfu_main_download_metadata (self, &error))
|
1031 | |
gfu_main_error_dialog (self, _("Failed to download metadata"), error->message);
|
1032 | |
}
|
1033 | |
|
1034 | |
static gboolean
|
1035 | |
gfu_main_install_release_to_device (GfuMain *self,
|
1036 | |
FwupdDevice *dev,
|
1037 | |
FwupdRelease *rel,
|
1038 | |
GError **error)
|
1039 | |
{
|
1040 | |
GPtrArray *checksums;
|
1041 | |
const gchar *remote_id;
|
1042 | |
const gchar *uri_tmp;
|
1043 | |
g_autofree gchar *fn = NULL;
|
1044 | |
g_autofree gchar *uri_str = NULL;
|
1045 | |
g_autofree gchar *install_str = NULL;
|
1046 | |
g_autoptr(SoupURI) uri = NULL;
|
1047 | |
|
1048 | |
/* work out what remote-specific URI fields this should use */
|
1049 | |
uri_tmp = fwupd_release_get_uri (rel);
|
1050 | |
remote_id = fwupd_release_get_remote_id (rel);
|
1051 | |
if (remote_id != NULL) {
|
1052 | |
g_autoptr(FwupdRemote) remote = NULL;
|
1053 | |
remote = fwupd_client_get_remote_by_id (self->client,
|
1054 | |
remote_id,
|
1055 | |
NULL,
|
1056 | |
error);
|
1057 | |
if (remote == NULL)
|
1058 | |
return FALSE;
|
1059 | |
|
1060 | |
/* local and directory remotes have the firmware already */
|
1061 | |
if (fwupd_remote_get_kind (remote) == FWUPD_REMOTE_KIND_LOCAL) {
|
1062 | |
const gchar *fn_cache = fwupd_remote_get_filename_cache (remote);
|
1063 | |
g_autofree gchar *path = g_path_get_dirname (fn_cache);
|
1064 | |
|
1065 | |
fn = g_build_filename (path, uri_tmp, NULL);
|
1066 | |
} else if (fwupd_remote_get_kind (remote) == FWUPD_REMOTE_KIND_DIRECTORY) {
|
1067 | |
fn = g_strdup (uri_tmp + 7);
|
1068 | |
}
|
1069 | |
/* install with flags chosen by the user */
|
1070 | |
if (fn != NULL) {
|
1071 | |
return fwupd_client_install (self->client,
|
1072 | |
fwupd_device_get_id (dev),
|
1073 | |
fn, self->flags, NULL, error);
|
1074 | |
}
|
1075 | |
|
1076 | |
uri_str = fwupd_remote_build_firmware_uri (remote, uri_tmp, error);
|
1077 | |
if (uri_str == NULL)
|
1078 | |
return FALSE;
|
1079 | |
} else {
|
1080 | |
uri_str = g_strdup (uri_tmp);
|
1081 | |
}
|
1082 | |
|
1083 | |
/* download file */
|
1084 | |
g_debug ("Downloading %s for %s...\n",
|
1085 | |
fwupd_release_get_version (rel),
|
1086 | |
fwupd_device_get_name (dev));
|
1087 | |
gfu_main_set_install_loading_label (self, _("Preparing to download file..."));
|
1088 | |
/* place in gfu cache directory */
|
1089 | |
fn = gfu_get_user_cache_path (uri_str);
|
1090 | |
/* TRANSLATORS: creating directory for the firmware download */
|
1091 | |
gfu_main_set_install_loading_label (self, _("Creating cache path..."));
|
1092 | |
if (!gfu_common_mkdir_parent (fn, error))
|
1093 | |
return FALSE;
|
1094 | |
checksums = fwupd_release_get_checksums (rel);
|
1095 | |
uri = soup_uri_new (uri_str);
|
1096 | |
if (!gfu_main_download_file (self, uri, fn,
|
1097 | |
fwupd_checksum_get_best (checksums),
|
1098 | |
error))
|
1099 | |
return FALSE;
|
1100 | |
/* if the device specifies ONLY_OFFLINE automatically set this flag */
|
1101 | |
if (fwupd_device_has_flag (dev, FWUPD_DEVICE_FLAG_ONLY_OFFLINE))
|
1102 | |
self->flags |= FWUPD_INSTALL_FLAG_OFFLINE;
|
1103 | |
install_str = gfu_operation_to_string (self->current_operation, dev);
|
1104 | |
gfu_main_set_install_loading_label (self, install_str);
|
1105 | |
g_timer_start (self->time_elapsed);
|
1106 | |
return fwupd_client_install (self->client,
|
1107 | |
fwupd_device_get_id (dev), fn,
|
1108 | |
self->flags, NULL, error);
|
|
887 |
|
|
888 |
gfu_main_set_install_loading_label (self, _("Refreshing remotes..."));
|
|
889 |
gfu_main_show_install_loading (self, TRUE);
|
|
890 |
fwupd_client_get_remotes_async (self->client,
|
|
891 |
self->cancellable,
|
|
892 |
gfu_main_get_remotes_cb,
|
|
893 |
self);
|
1109 | 894 |
}
|
1110 | 895 |
|
1111 | 896 |
/* used to retrieve the current device post-install */
|
|
1115 | 900 |
} GfuPostInstallHelper;
|
1116 | 901 |
|
1117 | 902 |
static void
|
|
903 |
gfu_main_show_update_message (GfuMain *self, const gchar *str)
|
|
904 |
{
|
|
905 |
GtkWindow *window;
|
|
906 |
GtkWidget *dialog;
|
|
907 |
|
|
908 |
window = GTK_WINDOW (gtk_builder_get_object (self->builder, "dialog_main"));
|
|
909 |
dialog = gtk_message_dialog_new (window,
|
|
910 |
GTK_DIALOG_MODAL,
|
|
911 |
GTK_MESSAGE_QUESTION,
|
|
912 |
GTK_BUTTONS_YES_NO,
|
|
913 |
/* TRANSLATORS: prompting a reboot to do something */
|
|
914 |
"%s", _("The update requires further action"));
|
|
915 |
gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog), "%s", str);
|
|
916 |
gtk_dialog_run (GTK_DIALOG (dialog));
|
|
917 |
gtk_widget_destroy (dialog);
|
|
918 |
}
|
|
919 |
|
|
920 |
static void
|
1118 | 921 |
gfu_main_update_devices_post_install_cb (GObject *source_object, GAsyncResult *res, gpointer user_data)
|
1119 | 922 |
{
|
1120 | 923 |
GtkContainer *w;
|
1121 | 924 |
GtkWidget *l = NULL;
|
1122 | |
GPtrArray *devices;
|
1123 | |
GfuPostInstallHelper *helper = (GfuPostInstallHelper*)user_data;
|
1124 | |
g_autoptr(GError) error = NULL;
|
1125 | |
g_autoptr(GVariant) tmp = g_dbus_proxy_call_finish (helper->self->proxy, res, &error);
|
|
925 |
g_autoptr(GPtrArray) devices = NULL;
|
|
926 |
GfuPostInstallHelper *helper = (GfuPostInstallHelper*) user_data;
|
|
927 |
g_autoptr(GError) error = NULL;
|
1126 | 928 |
|
1127 | 929 |
/* clear out device list */
|
1128 | 930 |
w = GTK_CONTAINER (gtk_builder_get_object (helper->self->builder, "listbox_main"));
|
1129 | 931 |
gtk_list_box_unselect_all (GTK_LIST_BOX (w));
|
1130 | 932 |
gtk_container_foreach (w, (GtkCallback) gfu_main_remove_row, w);
|
1131 | 933 |
|
1132 | |
if (tmp == NULL) {
|
|
934 |
devices = fwupd_client_get_devices_finish (FWUPD_CLIENT (source_object), res, &error);
|
|
935 |
if (devices == NULL) {
|
1133 | 936 |
gfu_main_error_dialog (helper->self, _("Failed to load device list"), error->message);
|
1134 | 937 |
return;
|
1135 | 938 |
}
|
1136 | |
|
1137 | |
devices = fwupd_device_array_from_variant (tmp);
|
1138 | 939 |
|
1139 | 940 |
/* create a row in the listbox for each updatable device */
|
1140 | 941 |
for (guint i = 0; i < devices->len; i++) {
|
|
1156 | 957 |
}
|
1157 | 958 |
}
|
1158 | 959 |
|
|
960 |
/* show any manual action required */
|
|
961 |
if (helper->self->current_message != NULL) {
|
|
962 |
gfu_main_show_update_message (helper->self, helper->self->current_message);
|
|
963 |
g_clear_pointer (&helper->self->current_message, g_free);
|
|
964 |
}
|
|
965 |
|
1159 | 966 |
/* reboot or shutdown if necessary (UEFI update) */
|
1160 | 967 |
gfu_main_reboot_shutdown_prompt (helper->self);
|
1161 | 968 |
|
|
1166 | 973 |
}
|
1167 | 974 |
|
1168 | 975 |
/* update release list */
|
1169 | |
g_dbus_proxy_call (helper->self->proxy,
|
1170 | |
"GetReleases",
|
1171 | |
g_variant_new ("(s)", helper->device_id),
|
1172 | |
G_DBUS_CALL_FLAGS_NONE,
|
1173 | |
-1,
|
1174 | |
helper->self->cancellable,
|
1175 | |
(GAsyncReadyCallback) gfu_main_update_releases_cb,
|
1176 | |
helper->self);
|
|
976 |
fwupd_client_get_releases_async (helper->self->client,
|
|
977 |
helper->device_id,
|
|
978 |
helper->self->cancellable,
|
|
979 |
(GAsyncReadyCallback) gfu_main_update_releases_cb,
|
|
980 |
helper->self);
|
|
981 |
}
|
|
982 |
|
|
983 |
static void
|
|
984 |
gfu_main_install_release_cb (GObject *source, GAsyncResult *res, gpointer user_data)
|
|
985 |
{
|
|
986 |
GfuMain *self = (GfuMain *) user_data;
|
|
987 |
g_autoptr(GError) error = NULL;
|
|
988 |
GfuPostInstallHelper *helper = NULL;
|
|
989 |
GtkWidget *dialog;
|
|
990 |
GtkWidget *window;
|
|
991 |
|
|
992 |
if (!fwupd_client_install_bytes_finish (FWUPD_CLIENT (source), res, &error)) {
|
|
993 |
gfu_main_error_dialog (self, _("Failed to install firmware"), error->message);
|
|
994 |
gfu_main_show_install_loading (self, FALSE);
|
|
995 |
return;
|
|
996 |
}
|
|
997 |
|
|
998 |
/* create helper struct */
|
|
999 |
helper = g_new0 (GfuPostInstallHelper, 1);
|
|
1000 |
helper->self = self;
|
|
1001 |
helper->device_id = fwupd_device_get_id (self->device);
|
|
1002 |
|
|
1003 |
/* update device list */
|
|
1004 |
fwupd_client_get_devices_async (self->client,
|
|
1005 |
self->cancellable,
|
|
1006 |
gfu_main_update_devices_post_install_cb,
|
|
1007 |
helper);
|
|
1008 |
|
|
1009 |
gfu_main_show_install_loading (self, FALSE);
|
|
1010 |
|
|
1011 |
g_debug ("Installation complete.\n");
|
|
1012 |
// FIXME: device-changed signal
|
|
1013 |
|
|
1014 |
if (fwupd_device_get_flags (self->device) & FWUPD_DEVICE_FLAG_NEEDS_SHUTDOWN ||
|
|
1015 |
fwupd_device_get_flags (self->device) & FWUPD_DEVICE_FLAG_NEEDS_REBOOT)
|
|
1016 |
return;
|
|
1017 |
|
|
1018 |
window = GTK_WIDGET (gtk_builder_get_object (self->builder, "dialog_main"));
|
|
1019 |
dialog = gtk_message_dialog_new (GTK_WINDOW (window),
|
|
1020 |
GTK_DIALOG_MODAL,
|
|
1021 |
GTK_MESSAGE_INFO,
|
|
1022 |
GTK_BUTTONS_OK,
|
|
1023 |
/* TRANSLATORS: inform the user that the installation was successful onto the device */
|
|
1024 |
"%s", _("Installation successful"));
|
|
1025 |
gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
|
|
1026 |
_("Installed firmware version %s on %s"),
|
|
1027 |
fwupd_release_get_version (self->release),
|
|
1028 |
fwupd_device_get_name (self->device));
|
|
1029 |
|
|
1030 |
gtk_dialog_run (GTK_DIALOG (dialog));
|
|
1031 |
gtk_widget_destroy (dialog);
|
|
1032 |
self->flags = FWUPD_INSTALL_FLAG_NONE;
|
1177 | 1033 |
}
|
1178 | 1034 |
|
1179 | 1035 |
static void
|
|
1226 | 1082 |
gtk_dialog_add_button (GTK_DIALOG (dialog), _("Downgrade"), GTK_RESPONSE_OK);
|
1227 | 1083 |
}
|
1228 | 1084 |
}
|
1229 | |
#if FWUPD_CHECK_VERSION(1,3,3)
|
1230 | 1085 |
if (fwupd_device_has_flag (self->device, FWUPD_DEVICE_FLAG_USABLE_DURING_UPDATE))
|
1231 | 1086 |
gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
|
1232 | 1087 |
_("The device will remain usable for the duration of the update"));
|
1233 | 1088 |
else
|
1234 | 1089 |
gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
|
1235 | 1090 |
_("The device will be unusable while the update is installing"));
|
1236 | |
#else
|
1237 | |
gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
|
1238 | |
reinstall? _("Reinstall this firmware file?"): _("Install this firmware file?"));
|
1239 | |
#endif
|
1240 | 1091 |
|
1241 | 1092 |
/* handle dialog response */
|
1242 | 1093 |
switch (gtk_dialog_run (GTK_DIALOG (dialog))) {
|
1243 | 1094 |
case GTK_RESPONSE_OK:
|
1244 | 1095 |
{
|
1245 | |
/* keep track of which device is being installed upon */
|
1246 | |
g_autoptr(GString) device_id = g_string_new (NULL);
|
1247 | |
g_string_assign (device_id, fwupd_device_get_id (self->device));
|
1248 | |
|
1249 | 1096 |
gtk_widget_destroy (dialog);
|
1250 | 1097 |
|
1251 | 1098 |
/* begin installing, show loading animation */
|
1252 | 1099 |
gfu_main_show_install_loading (self, TRUE);
|
1253 | |
|
1254 | |
if (!gfu_main_install_release_to_device (self, self->device, self->release, &error)) {
|
1255 | |
gfu_main_show_install_loading (self, FALSE);
|
1256 | |
gfu_main_error_dialog (self, _("Failed to install firmware release"), error->message);
|
1257 | |
} else {
|
1258 | |
/* create helper struct */
|
1259 | |
GfuPostInstallHelper *helper = g_new0 (GfuPostInstallHelper, 1);
|
1260 | |
guint64 flags = fwupd_device_get_flags (self->device);
|
1261 | |
helper->self = self;
|
1262 | |
helper->device_id = device_id->str;
|
1263 | |
|
1264 | |
/* update device list */
|
1265 | |
g_dbus_proxy_call (self->proxy,
|
1266 | |
"GetDevices",
|
1267 | |
NULL,
|
1268 | |
G_DBUS_CALL_FLAGS_NONE,
|
1269 | |
-1,
|
1270 | |
self->cancellable,
|
1271 | |
(GAsyncReadyCallback) gfu_main_update_devices_post_install_cb,
|
1272 | |
helper);
|
1273 | |
|
1274 | |
gfu_main_show_install_loading (self, FALSE);
|
1275 | |
|
1276 | |
g_debug ("Installation complete.\n");
|
1277 | |
// FIXME: device-changed signal
|
1278 | |
|
1279 | |
if (flags & FWUPD_DEVICE_FLAG_NEEDS_SHUTDOWN ||
|
1280 | |
flags & FWUPD_DEVICE_FLAG_NEEDS_REBOOT)
|
1281 | |
break;
|
1282 | |
|
1283 | |
dialog = gtk_message_dialog_new (GTK_WINDOW (window),
|
1284 | |
GTK_DIALOG_MODAL,
|
1285 | |
GTK_MESSAGE_INFO,
|
1286 | |
GTK_BUTTONS_OK,
|
1287 | |
/* TRANSLATORS: inform the user that the installation was successful onto the device */
|
1288 | |
"%s", _("Installation successful"));
|
1289 | |
gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
|
1290 | |
_("Installed firmware version %s on %s"),
|
1291 | |
fwupd_release_get_version (self->release),
|
1292 | |
fwupd_device_get_name (self->device));
|
1293 | |
|
1294 | |
gtk_dialog_run (GTK_DIALOG (dialog));
|
1295 | |
gtk_widget_destroy (dialog);
|
1296 | |
}
|
1297 | |
self->flags = FWUPD_INSTALL_FLAG_NONE;
|
|
1100 |
gfu_main_set_install_loading_label (self, _("Downloading file..."));
|
|
1101 |
fwupd_client_install_release2_async (self->client,
|
|
1102 |
self->device,
|
|
1103 |
self->release,
|
|
1104 |
self->flags,
|
|
1105 |
FWUPD_CLIENT_DOWNLOAD_FLAG_NONE,
|
|
1106 |
self->cancellable,
|
|
1107 |
gfu_main_install_release_cb,
|
|
1108 |
self);
|
1298 | 1109 |
break;
|
1299 | 1110 |
}
|
1300 | 1111 |
case GTK_RESPONSE_CANCEL:
|
|
1370 | 1181 |
}
|
1371 | 1182 |
|
1372 | 1183 |
static void
|
|
1184 |
gfu_main_verify_update_cb (GObject *source, GAsyncResult *res, gpointer user_data)
|
|
1185 |
{
|
|
1186 |
GfuMain *self = (GfuMain *) user_data;
|
|
1187 |
g_autoptr(GError) error = NULL;
|
|
1188 |
|
|
1189 |
if (!fwupd_client_verify_update_finish (FWUPD_CLIENT (source), res, &error)) {
|
|
1190 |
/* TRANSLATORS: verify means checking the actual checksum of the firmware */
|
|
1191 |
gfu_main_error_dialog (self, _("Failed to update checksums"), error->message);
|
|
1192 |
return;
|
|
1193 |
}
|
|
1194 |
gfu_main_refresh_ui (self);
|
|
1195 |
}
|
|
1196 |
|
|
1197 |
static void
|
1373 | 1198 |
gfu_main_device_verify_update_cb (GtkWidget *widget, GfuMain *self)
|
1374 | 1199 |
{
|
1375 | 1200 |
GtkWidget *dialog;
|
1376 | 1201 |
GtkWidget *window = GTK_WIDGET (gtk_builder_get_object (self->builder, "dialog_main"));
|
1377 | |
g_autoptr(GError) error = NULL;
|
1378 | 1202 |
|
1379 | 1203 |
dialog = gtk_message_dialog_new (GTK_WINDOW (window),
|
1380 | 1204 |
GTK_DIALOG_MODAL,
|
|
1387 | 1211 |
switch (gtk_dialog_run (GTK_DIALOG (dialog))) {
|
1388 | 1212 |
case GTK_RESPONSE_YES:
|
1389 | 1213 |
gtk_widget_destroy (dialog);
|
1390 | |
g_clear_error (&error);
|
1391 | |
if (!fwupd_client_verify_update (self->client,
|
1392 | |
fwupd_device_get_id (self->device),
|
1393 | |
self->cancellable,
|
1394 | |
&error)) {
|
1395 | |
/* TRANSLATORS: verify means checking the actual checksum of the firmware */
|
1396 | |
gfu_main_error_dialog (self, _("Failed to update checksums"), error->message);
|
1397 | |
}
|
1398 | |
gfu_main_refresh_ui (self);
|
|
1214 |
fwupd_client_verify_update_async (self->client,
|
|
1215 |
fwupd_device_get_id (self->device),
|
|
1216 |
self->cancellable,
|
|
1217 |
gfu_main_verify_update_cb,
|
|
1218 |
self);
|
1399 | 1219 |
return;
|
1400 | 1220 |
default:
|
1401 | 1221 |
gtk_widget_destroy (dialog);
|
|
1484 | 1304 |
|
1485 | 1305 |
/* async call for releases */
|
1486 | 1306 |
if (fwupd_device_has_flag (self->device, FWUPD_DEVICE_FLAG_UPDATABLE)) {
|
1487 | |
g_dbus_proxy_call (self->proxy,
|
1488 | |
"GetReleases",
|
1489 | |
g_variant_new ("(s)", fwupd_device_get_id (self->device)),
|
1490 | |
G_DBUS_CALL_FLAGS_NONE,
|
1491 | |
-1,
|
1492 | |
self->cancellable,
|
1493 | |
(GAsyncReadyCallback) gfu_main_update_releases_cb,
|
1494 | |
self);
|
|
1307 |
fwupd_client_get_releases_async (self->client,
|
|
1308 |
fwupd_device_get_id (self->device),
|
|
1309 |
self->cancellable,
|
|
1310 |
(GAsyncReadyCallback) gfu_main_update_releases_cb,
|
|
1311 |
self);
|
1495 | 1312 |
}
|
1496 | 1313 |
|
1497 | 1314 |
gfu_main_refresh_ui (self);
|
|
1535 | 1352 |
}
|
1536 | 1353 |
|
1537 | 1354 |
static void
|
1538 | |
gfu_main_signals_cb (GDBusProxy *proxy,
|
1539 | |
const gchar *sender_name,
|
1540 | |
const gchar *signal_name,
|
1541 | |
GVariant *parameters,
|
1542 | |
GfuMain *self)
|
1543 | |
{
|
1544 | |
g_autoptr(FwupdDevice) dev = NULL;
|
1545 | |
if (g_strcmp0 (signal_name, "DeviceAdded") == 0) {
|
1546 | |
dev = fwupd_device_from_variant (parameters);
|
1547 | |
g_debug ("Emitting ::device-added(%s)",
|
1548 | |
fwupd_device_get_id (dev));
|
1549 | |
gfu_main_device_added_cb (self->client, dev, self);
|
1550 | |
return;
|
1551 | |
}
|
1552 | |
if (g_strcmp0 (signal_name, "DeviceRemoved") == 0) {
|
1553 | |
dev = fwupd_device_from_variant (parameters);
|
1554 | |
g_debug ("Emitting ::device-removed(%s)",
|
1555 | |
fwupd_device_get_id (dev));
|
1556 | |
gfu_main_device_removed_cb (self->client, dev, self);
|
1557 | |
return;
|
1558 | |
}
|
1559 | |
if (g_strcmp0 (signal_name, "DeviceChanged") == 0) {
|
1560 | |
FwupdStatus status = fwupd_client_get_status (self->client);
|
1561 | |
gint percentage;
|
1562 | |
g_autoptr(GString) status_str = g_string_new (NULL);
|
1563 | |
g_autofree gchar *device_str = NULL;
|
1564 | |
|
1565 | |
dev = fwupd_device_from_variant (parameters);
|
1566 | |
|
1567 | |
/* update progress */
|
1568 | |
percentage = fwupd_client_get_percentage (self->client);
|
1569 | |
g_string_append_printf (status_str, "%s: %d%%\n",
|
1570 | |
gfu_status_to_string (status),
|
1571 | |
percentage);
|
1572 | |
|
1573 | |
/* once we have good data show an estimate of time remaining */
|
1574 | |
if (gfu_main_estimate_ready (self, percentage)) {
|
1575 | |
g_autofree gchar *remaining = gfu_main_time_remaining_str (self);
|
1576 | |
if (remaining != NULL)
|
1577 | |
g_string_append_printf (status_str, "%s…", remaining);
|
1578 | |
}
|
1579 | |
gfu_main_set_install_status_label (self, status_str->str);
|
1580 | |
|
1581 | |
/* same as last time, so ignore */
|
1582 | |
if (self->device != NULL &&
|
1583 | |
fwupd_device_compare (self->device, dev) == 0)
|
|
1355 |
gfu_main_set_feature_flags_cb (GObject *source, GAsyncResult *res, gpointer user_data)
|
|
1356 |
{
|
|
1357 |
GfuMain *self = (GfuMain *) user_data;
|
|
1358 |
g_autoptr(GError) error = NULL;
|
|
1359 |
if (!fwupd_client_set_feature_flags_finish (FWUPD_CLIENT (source), res, &error)) {
|
|
1360 |
g_warning ("%s", error->message);
|
|
1361 |
if (g_error_matches (error,
|
|
1362 |
FWUPD_ERROR,
|
|
1363 |
FWUPD_ERROR_NOT_SUPPORTED)) {
|
|
1364 |
gfu_main_error_fatal (self, _("The fwupd service is not available for your OS."));
|
1584 | 1365 |
return;
|
1585 | |
|
1586 | |
device_str = gfu_operation_to_string (self->current_operation,
|
1587 | |
dev);
|
1588 | |
gfu_main_set_install_loading_label (self, device_str);
|
1589 | |
|
1590 | |
return;
|
1591 | |
}
|
1592 | |
|
1593 | |
g_debug ("Unknown signal name '%s' from %s", signal_name, sender_name);
|
1594 | |
}
|
1595 | |
|
1596 | |
static void
|
1597 | |
gfu_main_proxy_new_cb (GObject *source_object, GAsyncResult *res, gpointer user_data)
|
1598 | |
{
|
1599 | |
g_autoptr(GError) error = NULL;
|
|
1366 |
}
|
|
1367 |
}
|
|
1368 |
fwupd_client_get_devices_async (self->client, self->cancellable,
|
|
1369 |
gfu_main_update_devices_cb, self);
|
|
1370 |
fwupd_client_get_remotes_async (self->client, self->cancellable,
|
|
1371 |
gfu_main_update_remotes_cb, self);
|
|
1372 |
}
|
|
1373 |
|
|
1374 |
static void
|
|
1375 |
gfu_main_unlock_cb (GObject *source, GAsyncResult *res, gpointer user_data)
|
|
1376 |
{
|
1600 | 1377 |
GfuMain *self = (GfuMain *) user_data;
|
1601 | |
self->proxy = g_dbus_proxy_new_for_bus_finish (res, &error);
|
1602 | |
|
1603 | |
if (self->proxy == NULL) {
|
1604 | |
gfu_main_error_dialog (self, _("Error connecting to fwupd"), error->message);
|
1605 | |
return;
|
1606 | |
}
|
1607 | |
|
1608 | |
/* async call for devices */
|
1609 | |
g_dbus_proxy_call (self->proxy,
|
1610 | |
"GetDevices",
|
1611 | |
NULL,
|
1612 | |
G_DBUS_CALL_FLAGS_NONE,
|
1613 | |
-1,
|
1614 | |
self->cancellable,
|
1615 | |
(GAsyncReadyCallback) gfu_main_update_devices_cb,
|
1616 | |
self);
|
1617 | |
|
1618 | |
/* async call for remotes */
|
1619 | |
g_dbus_proxy_call (self->proxy,
|
1620 | |
"GetRemotes",
|
1621 | |
NULL,
|
1622 | |
G_DBUS_CALL_FLAGS_NONE,
|
1623 | |
-1,
|
1624 | |
self->cancellable,
|
1625 | |
(GAsyncReadyCallback) gfu_main_update_remotes_cb,
|
1626 | |
self);
|
1627 | |
|
1628 | |
/* connecting signals for updating devices */
|
1629 | |
g_signal_connect (self->proxy, "g-signal",
|
1630 | |
G_CALLBACK (gfu_main_signals_cb), self);
|
|
1378 |
g_autoptr(GError) error = NULL;
|
|
1379 |
|
|
1380 |
if (!fwupd_client_verify_update_finish (FWUPD_CLIENT (source), res, &error)) {
|
|
1381 |
gfu_main_error_dialog (self, _("Failed to unlock device"), error->message);
|
|
1382 |
return;
|
|
1383 |
}
|
|
1384 |
gfu_main_reboot_shutdown_prompt (self);
|
1631 | 1385 |
}
|
1632 | 1386 |
|
1633 | 1387 |
static void
|
1634 | 1388 |
gfu_main_device_unlock_cb (GtkWidget *widget, GfuMain *self)
|
1635 | 1389 |
{
|
1636 | |
g_autoptr(GError) error = NULL;
|
1637 | |
if (!fwupd_client_unlock (self->client,
|
1638 | |
fwupd_device_get_id (self->device),
|
1639 | |
self->cancellable,
|
1640 | |
&error)) {
|
1641 | |
gfu_main_error_dialog (self, _("Failed to unlock device"), error->message);
|
1642 | |
} else {
|
1643 | |
gfu_main_reboot_shutdown_prompt (self);
|
1644 | |
}
|
|
1390 |
fwupd_client_unlock_async (self->client,
|
|
1391 |
fwupd_device_get_id (self->device),
|
|
1392 |
self->cancellable,
|
|
1393 |
gfu_main_unlock_cb,
|
|
1394 |
self);
|
1645 | 1395 |
}
|
1646 | 1396 |
|
1647 | 1397 |
static void
|
|
1655 | 1405 |
{
|
1656 | 1406 |
if (response_id == GTK_RESPONSE_CLOSE)
|
1657 | 1407 |
gtk_info_bar_set_revealed (infobar, FALSE);
|
|
1408 |
}
|
|
1409 |
|
|
1410 |
static void
|
|
1411 |
gfu_main_client_connect_cb (GObject *source, GAsyncResult *res, gpointer user_data)
|
|
1412 |
{
|
|
1413 |
GfuMain *self = (GfuMain *) user_data;
|
|
1414 |
g_autoptr(GError) error = NULL;
|
|
1415 |
|
|
1416 |
/* get result */
|
|
1417 |
if (!fwupd_client_connect_finish (FWUPD_CLIENT (source), res, &error)) {
|
|
1418 |
g_warning ("%s", error->message);
|
|
1419 |
gfu_main_error_fatal (self, _("The fwupd service is not available for your OS."));
|
|
1420 |
return;
|
|
1421 |
}
|
|
1422 |
|
|
1423 |
/* get data */
|
|
1424 |
fwupd_client_set_feature_flags_async (self->client,
|
|
1425 |
FWUPD_FEATURE_FLAG_UPDATE_ACTION,
|
|
1426 |
self->cancellable,
|
|
1427 |
gfu_main_set_feature_flags_cb, self);
|
1658 | 1428 |
}
|
1659 | 1429 |
|
1660 | 1430 |
static void
|
|
1729 | 1499 |
gfu_main_refresh_ui (self);
|
1730 | 1500 |
gtk_widget_show (main_window);
|
1731 | 1501 |
|
1732 | |
g_dbus_proxy_new_for_bus (G_BUS_TYPE_SYSTEM,
|
1733 | |
G_DBUS_PROXY_FLAGS_NONE,
|
1734 | |
NULL,
|
1735 | |
FWUPD_DBUS_SERVICE,
|
1736 | |
FWUPD_DBUS_PATH,
|
1737 | |
FWUPD_DBUS_INTERFACE,
|
1738 | |
self->cancellable,
|
1739 | |
(GAsyncReadyCallback) gfu_main_proxy_new_cb,
|
1740 | |
self);
|
|
1502 |
/* connect to fwupd */
|
|
1503 |
fwupd_client_connect_async (self->client, self->cancellable,
|
|
1504 |
gfu_main_client_connect_cb, self);
|
|
1505 |
}
|
|
1506 |
|
|
1507 |
static void
|
|
1508 |
gfu_main_client_device_changed_cb (FwupdClient *client,
|
|
1509 |
FwupdDevice *device,
|
|
1510 |
GfuMain *self)
|
|
1511 |
{
|
|
1512 |
FwupdStatus status = fwupd_client_get_status (self->client);
|
|
1513 |
gint percentage;
|
|
1514 |
g_autoptr(GString) status_str = g_string_new (NULL);
|
|
1515 |
g_autofree gchar *device_str = NULL;
|
|
1516 |
|
|
1517 |
if (self->current_message == NULL) {
|
|
1518 |
const gchar *tmp = fwupd_device_get_update_message (device);
|
|
1519 |
if (tmp != NULL)
|
|
1520 |
self->current_message = g_strdup (tmp);
|
|
1521 |
}
|
|
1522 |
|
|
1523 |
/* update progress */
|
|
1524 |
percentage = fwupd_client_get_percentage (self->client);
|
|
1525 |
g_string_append_printf (status_str, "%s: %d%%\n",
|
|
1526 |
gfu_status_to_string (status),
|
|
1527 |
percentage);
|
|
1528 |
|
|
1529 |
/* once we have good data show an estimate of time remaining */
|
|
1530 |
if (gfu_main_estimate_ready (self, percentage)) {
|
|
1531 |
g_autofree gchar *remaining = gfu_main_time_remaining_str (self);
|
|
1532 |
if (remaining != NULL)
|
|
1533 |
g_string_append_printf (status_str, "%s…", remaining);
|
|
1534 |
}
|
|
1535 |
gfu_main_set_install_status_label (self, status_str->str);
|
|
1536 |
|
|
1537 |
/* same as last time, so ignore */
|
|
1538 |
if (self->device != NULL &&
|
|
1539 |
fwupd_device_compare (self->device, device) == 0)
|
|
1540 |
return;
|
|
1541 |
|
|
1542 |
device_str = gfu_operation_to_string (self->current_operation, device);
|
|
1543 |
gfu_main_set_install_loading_label (self, device_str);
|
1741 | 1544 |
}
|
1742 | 1545 |
|
1743 | 1546 |
static void
|
|
1757 | 1560 |
g_object_unref (self->application);
|
1758 | 1561 |
if (self->releases != NULL)
|
1759 | 1562 |
g_ptr_array_unref (self->releases);
|
1760 | |
if (self->proxy != NULL)
|
1761 | |
g_object_unref (self->proxy);
|
1762 | |
if (self->soup_session != NULL)
|
1763 | |
g_object_unref (self->soup_session);
|
1764 | 1563 |
g_timer_destroy (self->time_elapsed);
|
|
1564 |
g_free (self->current_message);
|
1765 | 1565 |
g_free (self);
|
1766 | 1566 |
}
|
1767 | 1567 |
|
|
1800 | 1600 |
|
1801 | 1601 |
self->cancellable = g_cancellable_new ();
|
1802 | 1602 |
self->client = fwupd_client_new ();
|
|
1603 |
fwupd_client_set_user_agent_for_package (self->client, GETTEXT_PACKAGE, VERSION);
|
|
1604 |
g_signal_connect (self->client, "notify::percentage",
|
|
1605 |
G_CALLBACK (gfu_main_client_percentage_changed_cb), self);
|
|
1606 |
g_signal_connect (self->client, "device-changed",
|
|
1607 |
G_CALLBACK (gfu_main_client_device_changed_cb), self);
|
|
1608 |
g_signal_connect (self->client, "device-added",
|
|
1609 |
G_CALLBACK (gfu_main_device_added_cb), self);
|
|
1610 |
g_signal_connect (self->client, "device-removed",
|
|
1611 |
G_CALLBACK (gfu_main_device_removed_cb), self);
|
|
1612 |
|
1803 | 1613 |
self->time_elapsed = g_timer_new ();
|
1804 | 1614 |
|
1805 | 1615 |
/* ensure single instance */
|