From a1b9a7a181b4e7e8e4c689b734c9cedfd0799369 Mon Sep 17 00:00:00 2001 From: Marius Meisenzahl Date: Thu, 10 Dec 2020 19:51:03 +0100 Subject: [PATCH 01/96] Add D-Bus interface to interact with fwupd --- src/Interfaces/FwupdManager.vala | 50 ++++++++++++++++++++++++++++++++ src/Views/HardwareView.vala | 2 ++ src/meson.build | 1 + 3 files changed, 53 insertions(+) create mode 100644 src/Interfaces/FwupdManager.vala diff --git a/src/Interfaces/FwupdManager.vala b/src/Interfaces/FwupdManager.vala new file mode 100644 index 000000000..6d7e7d9be --- /dev/null +++ b/src/Interfaces/FwupdManager.vala @@ -0,0 +1,50 @@ +/* +* Copyright (c) 2020 elementary, Inc. (https://elementary.io) +* +* 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 3 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 +* +* Authored by: Marius Meisenzahl +*/ + +[DBus (name="org.freedesktop.fwupd")] +public interface About.FwupdInterface : Object { + [DBus (name = "HostProduct")] + public abstract string host_product { owned get; } +} + +public class About.FwupdManager : Object { + private FwupdInterface interface; + + static FwupdManager? instance = null; + public static FwupdManager get_instance () { + if (instance == null) { + instance = new FwupdManager (); + } + + return instance; + } + + private FwupdManager () {} + + construct { + try { + interface = Bus.get_proxy_sync (BusType.SYSTEM, "org.freedesktop.fwupd", "/"); + print ("HostProduct: %s\n", interface.host_product); + } catch (Error e) { + warning ("Could not connect to color interface: %s", e.message); + } + } +} diff --git a/src/Views/HardwareView.vala b/src/Views/HardwareView.vala index 8b3fb9842..9486cbbd9 100644 --- a/src/Views/HardwareView.vala +++ b/src/Views/HardwareView.vala @@ -52,6 +52,8 @@ public class About.HardwareView : Gtk.Grid { critical (e.message); } + var fwupd_manager = FwupdManager.get_instance (); + var manufacturer_logo = new Gtk.Image (); manufacturer_logo.icon_name = system_interface.icon_name; manufacturer_logo.hexpand = true; diff --git a/src/meson.build b/src/meson.build index 6d4d2631d..61bf690db 100644 --- a/src/meson.build +++ b/src/meson.build @@ -1,5 +1,6 @@ plug_files = files( 'Plug.vala', + 'Interfaces/FwupdManager.vala', 'Utils/ARMPartDecoder.vala', 'Views/HardwareView.vala' ) From 2414d8fab8bcbd0d83670a0766c377c346f84597 Mon Sep 17 00:00:00 2001 From: Marius Meisenzahl Date: Thu, 10 Dec 2020 20:37:39 +0100 Subject: [PATCH 02/96] Get device names --- src/Interfaces/FwupdManager.vala | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/Interfaces/FwupdManager.vala b/src/Interfaces/FwupdManager.vala index 6d7e7d9be..57b96c05a 100644 --- a/src/Interfaces/FwupdManager.vala +++ b/src/Interfaces/FwupdManager.vala @@ -23,6 +23,9 @@ public interface About.FwupdInterface : Object { [DBus (name = "HostProduct")] public abstract string host_product { owned get; } + + [DBus (name = "GetDevices")] + public abstract GLib.HashTable[] get_devices () throws GLib.Error; } public class About.FwupdManager : Object { @@ -42,7 +45,15 @@ public class About.FwupdManager : Object { construct { try { interface = Bus.get_proxy_sync (BusType.SYSTEM, "org.freedesktop.fwupd", "/"); - print ("HostProduct: %s\n", interface.host_product); + + var devices = interface.get_devices (); + foreach (var device in devices) { + foreach (var key in device.get_keys ()) { + if (key == "Name") { + print ("%s: %s\n", key, device.lookup (key).get_string ()); + } + } + } } catch (Error e) { warning ("Could not connect to color interface: %s", e.message); } From e8159de21c77a554c3d833e7abc9c61c0b7515dc Mon Sep 17 00:00:00 2001 From: Marius Meisenzahl Date: Thu, 10 Dec 2020 21:07:22 +0100 Subject: [PATCH 03/96] Add class for devices --- src/Interfaces/FwupdManager.vala | 41 +++++++++++++++++++++++++------- src/Objects/Device.vala | 36 ++++++++++++++++++++++++++++ src/Views/HardwareView.vala | 3 +++ src/meson.build | 1 + 4 files changed, 73 insertions(+), 8 deletions(-) create mode 100644 src/Objects/Device.vala diff --git a/src/Interfaces/FwupdManager.vala b/src/Interfaces/FwupdManager.vala index 57b96c05a..9f3fcb21c 100644 --- a/src/Interfaces/FwupdManager.vala +++ b/src/Interfaces/FwupdManager.vala @@ -42,20 +42,45 @@ public class About.FwupdManager : Object { private FwupdManager () {} - construct { - try { - interface = Bus.get_proxy_sync (BusType.SYSTEM, "org.freedesktop.fwupd", "/"); + public List get_devices () { + var devices_list = new List (); - var devices = interface.get_devices (); - foreach (var device in devices) { - foreach (var key in device.get_keys ()) { - if (key == "Name") { - print ("%s: %s\n", key, device.lookup (key).get_string ()); + try { + foreach (var _device in interface.get_devices ()) { + var device = new Device (); + foreach (var key in _device.get_keys ()) { + switch (key) { + case "DeviceId": + device.id = _device.lookup (key).get_string (); + break; + case "Name": + device.name = _device.lookup (key).get_string (); + break; + case "Summary": + device.summary = _device.lookup (key).get_string (); + break; + case "Icon": + var icons = _device.lookup (key).get_strv (); + device.icon = icons.length > 0 ? icons[0] : "unknown"; + break; + default: + break; } } + devices_list.append (device); } } catch (Error e) { warning ("Could not connect to color interface: %s", e.message); } + + return devices_list; + } + + construct { + try { + interface = Bus.get_proxy_sync (BusType.SYSTEM, "org.freedesktop.fwupd", "/"); + } catch (Error e) { + warning ("Could not connect to color interface: %s", e.message); + } } } diff --git a/src/Objects/Device.vala b/src/Objects/Device.vala new file mode 100644 index 000000000..be773b349 --- /dev/null +++ b/src/Objects/Device.vala @@ -0,0 +1,36 @@ +/* +* Copyright (c) 2020 elementary, Inc. (https://elementary.io) +* +* 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 3 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 +* +* Authored by: Marius Meisenzahl +*/ + +public class About.Device : Object { + public string id { get; set; } + public string name { get; set; } + public string summary { get; set; } + public string icon { get; set; } + + public string to_string () { + return "{id: %s, name: %s, icon: %s, summary: %s}".printf ( + id, + name, + icon, + summary + ); + } +} diff --git a/src/Views/HardwareView.vala b/src/Views/HardwareView.vala index 9486cbbd9..b7c1356b2 100644 --- a/src/Views/HardwareView.vala +++ b/src/Views/HardwareView.vala @@ -53,6 +53,9 @@ public class About.HardwareView : Gtk.Grid { } var fwupd_manager = FwupdManager.get_instance (); + foreach (var device in fwupd_manager.get_devices ()) { + print ("%s\n", device.to_string ()); + } var manufacturer_logo = new Gtk.Image (); manufacturer_logo.icon_name = system_interface.icon_name; diff --git a/src/meson.build b/src/meson.build index 61bf690db..08595f9f6 100644 --- a/src/meson.build +++ b/src/meson.build @@ -1,5 +1,6 @@ plug_files = files( 'Plug.vala', + 'Objects/Device.vala', 'Interfaces/FwupdManager.vala', 'Utils/ARMPartDecoder.vala', 'Views/HardwareView.vala' From 1e86f4dab78a11e1d9d96d38be5b9d989296b0c8 Mon Sep 17 00:00:00 2001 From: Marius Meisenzahl Date: Fri, 11 Dec 2020 18:15:38 +0100 Subject: [PATCH 04/96] Split into separate views --- src/Plug.vala | 307 +++--------------------------------- src/Views/FirmwareView.vala | 7 + src/Views/SystemView.vala | 290 ++++++++++++++++++++++++++++++++++ src/meson.build | 4 +- 4 files changed, 321 insertions(+), 287 deletions(-) create mode 100644 src/Views/FirmwareView.vala create mode 100644 src/Views/SystemView.vala diff --git a/src/Plug.vala b/src/Plug.vala index 4d8b738c2..b261b795a 100644 --- a/src/Plug.vala +++ b/src/Plug.vala @@ -16,11 +16,8 @@ // public class About.Plug : Switchboard.Plug { - private string kernel_version; - private string support_url; - private Gtk.Label based_off; - - private string upstream_release; + private Gtk.Stack stack; + private SystemView system_view; private Gtk.Grid main_grid; public Plug () { @@ -36,15 +33,31 @@ public class About.Plug : Switchboard.Plug { public override Gtk.Widget get_widget () { if (main_grid == null) { - setup_info (); - setup_ui (); + main_grid = new Gtk.Grid (); + + stack = new Gtk.Stack (); + + system_view = new SystemView (); + stack.add_titled (system_view, "system", _("System")); + + var firmware_view = new FirmwareView (); + stack.add_titled (firmware_view, "firmware", _("Firmware")); + + var stack_switcher = new Gtk.StackSwitcher (); + stack_switcher.stack = stack; + stack_switcher.halign = Gtk.Align.CENTER; + stack_switcher.homogeneous = true; + stack_switcher.margin = 24; + + main_grid.attach (stack_switcher, 0, 0, 1, 1); + main_grid.attach (stack, 0, 1, 1, 1); + main_grid.show_all (); } return main_grid; } public override void shown () { - main_grid.show (); } public override void hidden () { @@ -64,284 +77,6 @@ public class About.Plug : Switchboard.Plug { search_results.set ("%s → %s".printf (display_name, _("Updates")), ""); return search_results; } - - private void setup_info () { - // Upstream distro version (for "Built on" text) - // FIXME: Add distro specific field to /etc/os-release and use that instead - // Like "ELEMENTARY_UPSTREAM_DISTRO_NAME" or something - var file = File.new_for_path ("/etc/upstream-release/lsb-release"); - try { - var dis = new DataInputStream (file.read ()); - string line; - // Read lines until end of file (null) is reached - while ((line = dis.read_line (null)) != null) { - var distrib_component = line.split ("=", 2); - if (distrib_component.length == 2) { - upstream_release = distrib_component[1].replace ("\"", ""); - } - } - } catch (Error e) { - warning ("Couldn't read upstream lsb-release file, assuming none"); - upstream_release = null; - } - - var uts_name = Posix.utsname (); - kernel_version = "%s %s".printf (uts_name.sysname, uts_name.release); - } - - // Wires up and configures initial UI - private void setup_ui () { - var logo_icon_name = Environment.get_os_info ("LOGO"); - if (logo_icon_name == "" || logo_icon_name == null) { - logo_icon_name = "distributor-logo"; - } - - // Create the section about elementary OS - var logo = new Gtk.Image (); - logo.icon_name = logo_icon_name; - logo.pixel_size = 128; - logo.hexpand = true; - - var pretty_name = Environment.get_os_info (GLib.OsInfoKey.PRETTY_NAME); - if (pretty_name == "" || pretty_name == null) { - pretty_name = Environment.get_os_info (GLib.OsInfoKey.NAME); - } - - var title = new Gtk.Label (pretty_name); - title.get_style_context ().add_class (Granite.STYLE_CLASS_H2_LABEL); - title.set_selectable (true); - title.margin_bottom = 12; - title.ellipsize = Pango.EllipsizeMode.END; - - if (upstream_release != null) { - based_off = new Gtk.Label (_("Built on %s").printf (upstream_release)); - based_off.set_selectable (true); - } - - var kernel_version_label = new Gtk.Label (kernel_version); - kernel_version_label.set_selectable (true); - - var gtk_version_label = new Gtk.Label (_("GTK %u.%u.%u").printf ( - Gtk.get_major_version (), Gtk.get_minor_version (), Gtk.get_micro_version () - )); - gtk_version_label.selectable = true; - - var website_url = Environment.get_os_info (GLib.OsInfoKey.HOME_URL); - if (website_url == "" || website_url == null) { - website_url = "https://elementary.io"; - } - - var website_label = new Gtk.LinkButton.with_label (website_url, _("Website")); - website_label.halign = Gtk.Align.CENTER; - website_label.margin_top = 12; - - var help_button = new Gtk.Button.with_label ("?"); - help_button.get_style_context ().add_class ("circular"); - help_button.halign = Gtk.Align.END; - - support_url = Environment.get_os_info (GLib.OsInfoKey.SUPPORT_URL); - if (support_url == "" || support_url == null) { - support_url = "https://elementary.io/support"; - } - - help_button.clicked.connect (() => { - try { - AppInfo.launch_default_for_uri (support_url, null); - } catch (Error e) { - warning (e.message); - } - }); - - help_button.size_allocate.connect ( (alloc) => { - help_button.set_size_request (alloc.height, -1); - }); - - // Translate button - var translate_button = new Gtk.Button.with_label (_("Suggest Translations")); - translate_button.clicked.connect (() => { - try { - AppInfo.launch_default_for_uri ("https://l10n.elementary.io/projects/", null); - } catch (Error e) { - warning (e.message); - } - }); - - var bug_button = new Gtk.Button.with_label (_("Send Feedback")); - bug_button.clicked.connect (() => { - var appinfo = new GLib.DesktopAppInfo ("io.elementary.feedback.desktop"); - if (appinfo != null) { - try { - appinfo.launch (null, null); - } catch (Error e) { - critical (e.message); - launch_support_url (); - } - } else { - launch_support_url (); - } - }); - - Gtk.Button? update_button = null; - var appcenter_info = new GLib.DesktopAppInfo ("io.elementary.appcenter.desktop"); - if (appcenter_info != null) { - update_button = new Gtk.Button.with_label (_("Check for Updates")); - update_button.clicked.connect (() => { - appcenter_info.launch_action ("ShowUpdates", new GLib.AppLaunchContext ()); - }); - } - - - // Restore settings button - var settings_restore_button = new Gtk.Button.with_label (_("Restore Default Settings")); - settings_restore_button.clicked.connect (settings_restore_clicked); - - // Create a box for the buttons - var button_grid = new Gtk.ButtonBox (Gtk.Orientation.HORIZONTAL); - button_grid.halign = Gtk.Align.CENTER; - button_grid.spacing = 6; - button_grid.add (help_button); - button_grid.add (settings_restore_button); - button_grid.add (translate_button); - button_grid.add (bug_button); - - if (update_button != null) { - button_grid.add (update_button); - } - - button_grid.set_child_non_homogeneous (help_button, true); - - var software_grid = new Gtk.Grid (); - software_grid.orientation = Gtk.Orientation.VERTICAL; - software_grid.column_spacing = software_grid.row_spacing = 6; - software_grid.add (logo); - software_grid.add (title); - - if (upstream_release != null) { - software_grid.add (based_off); - } - - software_grid.add (kernel_version_label); - software_grid.add (gtk_version_label); - software_grid.add (website_label); - - var hardware_view = new HardwareView (); - - var description_size_group = new Gtk.SizeGroup (Gtk.SizeGroupMode.HORIZONTAL); - description_size_group.add_widget (hardware_view); - description_size_group.add_widget (software_grid); - - var description_grid = new Gtk.Grid (); - description_grid.halign = Gtk.Align.CENTER; - description_grid.valign = Gtk.Align.CENTER; - description_grid.vexpand = true; - description_grid.column_spacing = 24; - description_grid.margin_start = 12; - description_grid.margin_end = 12; - description_grid.add (software_grid); - description_grid.add (new Gtk.Separator (Gtk.Orientation.VERTICAL)); - description_grid.add (hardware_view); - - main_grid = new Gtk.Grid (); - main_grid.orientation = Gtk.Orientation.VERTICAL; - main_grid.halign = Gtk.Align.CENTER; - main_grid.row_spacing = 12; - main_grid.margin = 12; - main_grid.add (description_grid); - main_grid.add (button_grid); - main_grid.show_all (); - } - - private void launch_support_url () { - try { - AppInfo.launch_default_for_uri (support_url, null); - } catch (Error e) { - critical (e.message); - } - } - - /** - * returns true to continue, false to cancel - */ - private bool confirm_restore_action () { - var dialog = new Granite.MessageDialog.with_image_from_icon_name ( - _("System Settings Will Be Restored to The Factory Defaults"), - _("All system settings and data will be reset to the default values. Personal data, such as music and pictures, will be unaffected."), - "dialog-warning", - Gtk.ButtonsType.CANCEL - ); - dialog.transient_for = (Gtk.Window) main_grid.get_toplevel (); - - var continue_button = dialog.add_button (_("Restore Settings"), Gtk.ResponseType.ACCEPT); - continue_button.get_style_context ().add_class (Gtk.STYLE_CLASS_DESTRUCTIVE_ACTION); - - var result = dialog.run (); - dialog.destroy (); - - return result == Gtk.ResponseType.ACCEPT; - } - - private void settings_restore_clicked () { - if (confirm_restore_action ()) { - var all_schemas = get_pantheon_schemas (); - - foreach (var schema in all_schemas) { - reset_recursively (schema); - } - } - } - - private static void reset_all_keys (GLib.Settings settings) { - var schema = SettingsSchemaSource.get_default ().lookup ( - settings.schema_id, - true - ); - - foreach (var key in schema.list_keys ()) { - settings.reset (key); - } - } - - private static string[] get_pantheon_schemas () { - string[] schemas = {}; - string[] pantheon_schemas = {}; - string[] prefixes = { - "org.pantheon.desktop", - "io.elementary.desktop", - "io.elementary.onboarding", - "org.gnome.desktop", - "org.gnome.settings-daemon" - }; - - var sss = SettingsSchemaSource.get_default (); - - sss.list_schemas (true, out schemas, null); - - foreach (var schema in schemas) { - foreach (var prefix in prefixes) { - if (schema.has_prefix (prefix)) { - pantheon_schemas += schema; - } - } - } - return pantheon_schemas; - } - - private static void reset_recursively (string schema) { - var settings = new GLib.Settings (schema); - // change into delay mode - // so changes take place when apply () is called - settings.delay (); - - reset_all_keys (settings); - - foreach (var child in settings.list_children ()) { - var child_settings = settings.get_child (child); - - reset_all_keys (child_settings); - } - settings.apply (); - GLib.Settings.sync (); - } } public Switchboard.Plug get_plug (Module module) { diff --git a/src/Views/FirmwareView.vala b/src/Views/FirmwareView.vala new file mode 100644 index 000000000..7c67bb925 --- /dev/null +++ b/src/Views/FirmwareView.vala @@ -0,0 +1,7 @@ +public class About.FirmwareView : Gtk.Grid { + construct { + column_spacing = 12; + row_spacing = 24; + halign = Gtk.Align.CENTER; + } +} \ No newline at end of file diff --git a/src/Views/SystemView.vala b/src/Views/SystemView.vala new file mode 100644 index 000000000..5ad6d4d08 --- /dev/null +++ b/src/Views/SystemView.vala @@ -0,0 +1,290 @@ +public class About.SystemView : Gtk.Grid { + private string kernel_version; + private string support_url; + private Gtk.Label based_off; + + private string upstream_release; + + construct { + orientation = Gtk.Orientation.VERTICAL; + halign = Gtk.Align.CENTER; + row_spacing = 12; + margin = 12; + + setup_info (); + setup_ui (); + } + + private void setup_info () { + // Upstream distro version (for "Built on" text) + // FIXME: Add distro specific field to /etc/os-release and use that instead + // Like "ELEMENTARY_UPSTREAM_DISTRO_NAME" or something + var file = File.new_for_path ("/etc/upstream-release/lsb-release"); + try { + var dis = new DataInputStream (file.read ()); + string line; + // Read lines until end of file (null) is reached + while ((line = dis.read_line (null)) != null) { + var distrib_component = line.split ("=", 2); + if (distrib_component.length == 2) { + upstream_release = distrib_component[1].replace ("\"", ""); + } + } + } catch (Error e) { + warning ("Couldn't read upstream lsb-release file, assuming none"); + upstream_release = null; + } + + var uts_name = Posix.utsname (); + kernel_version = "%s %s".printf (uts_name.sysname, uts_name.release); + } + + // Wires up and configures initial UI + private void setup_ui () { + var logo_icon_name = Environment.get_os_info ("LOGO"); + if (logo_icon_name == "" || logo_icon_name == null) { + logo_icon_name = "distributor-logo"; + } + + // Create the section about elementary OS + var logo = new Gtk.Image (); + logo.icon_name = logo_icon_name; + logo.pixel_size = 128; + logo.hexpand = true; + + var pretty_name = Environment.get_os_info (GLib.OsInfoKey.PRETTY_NAME); + if (pretty_name == "" || pretty_name == null) { + pretty_name = Environment.get_os_info (GLib.OsInfoKey.NAME); + } + + var title = new Gtk.Label (pretty_name); + title.get_style_context ().add_class (Granite.STYLE_CLASS_H2_LABEL); + title.set_selectable (true); + title.margin_bottom = 12; + title.ellipsize = Pango.EllipsizeMode.END; + + if (upstream_release != null) { + based_off = new Gtk.Label (_("Built on %s").printf (upstream_release)); + based_off.set_selectable (true); + } + + var kernel_version_label = new Gtk.Label (kernel_version); + kernel_version_label.set_selectable (true); + + var gtk_version_label = new Gtk.Label (_("GTK %u.%u.%u").printf ( + Gtk.get_major_version (), Gtk.get_minor_version (), Gtk.get_micro_version () + )); + gtk_version_label.selectable = true; + + var website_url = Environment.get_os_info (GLib.OsInfoKey.HOME_URL); + if (website_url == "" || website_url == null) { + website_url = "https://elementary.io"; + } + + var website_label = new Gtk.LinkButton.with_label (website_url, _("Website")); + website_label.halign = Gtk.Align.CENTER; + website_label.margin_top = 12; + + var help_button = new Gtk.Button.with_label ("?"); + help_button.get_style_context ().add_class ("circular"); + help_button.halign = Gtk.Align.END; + + support_url = Environment.get_os_info (GLib.OsInfoKey.SUPPORT_URL); + if (support_url == "" || support_url == null) { + support_url = "https://elementary.io/support"; + } + + help_button.clicked.connect (() => { + try { + AppInfo.launch_default_for_uri (support_url, null); + } catch (Error e) { + warning (e.message); + } + }); + + help_button.size_allocate.connect ( (alloc) => { + help_button.set_size_request (alloc.height, -1); + }); + + // Translate button + var translate_button = new Gtk.Button.with_label (_("Suggest Translations")); + translate_button.clicked.connect (() => { + try { + AppInfo.launch_default_for_uri ("https://l10n.elementary.io/projects/", null); + } catch (Error e) { + warning (e.message); + } + }); + + var bug_button = new Gtk.Button.with_label (_("Send Feedback")); + bug_button.clicked.connect (() => { + var appinfo = new GLib.DesktopAppInfo ("io.elementary.feedback.desktop"); + if (appinfo != null) { + try { + appinfo.launch (null, null); + } catch (Error e) { + critical (e.message); + launch_support_url (); + } + } else { + launch_support_url (); + } + }); + + Gtk.Button? update_button = null; + var appcenter_info = new GLib.DesktopAppInfo ("io.elementary.appcenter.desktop"); + if (appcenter_info != null) { + update_button = new Gtk.Button.with_label (_("Check for Updates")); + update_button.clicked.connect (() => { + appcenter_info.launch_action ("ShowUpdates", new GLib.AppLaunchContext ()); + }); + } + + + // Restore settings button + var settings_restore_button = new Gtk.Button.with_label (_("Restore Default Settings")); + settings_restore_button.clicked.connect (settings_restore_clicked); + + // Create a box for the buttons + var button_grid = new Gtk.ButtonBox (Gtk.Orientation.HORIZONTAL); + button_grid.halign = Gtk.Align.CENTER; + button_grid.spacing = 6; + button_grid.add (help_button); + button_grid.add (settings_restore_button); + button_grid.add (translate_button); + button_grid.add (bug_button); + + if (update_button != null) { + button_grid.add (update_button); + } + + button_grid.set_child_non_homogeneous (help_button, true); + + var software_grid = new Gtk.Grid (); + software_grid.orientation = Gtk.Orientation.VERTICAL; + software_grid.column_spacing = software_grid.row_spacing = 6; + software_grid.add (logo); + software_grid.add (title); + + if (upstream_release != null) { + software_grid.add (based_off); + } + + software_grid.add (kernel_version_label); + software_grid.add (gtk_version_label); + software_grid.add (website_label); + + var hardware_view = new HardwareView (); + + var description_size_group = new Gtk.SizeGroup (Gtk.SizeGroupMode.HORIZONTAL); + description_size_group.add_widget (hardware_view); + description_size_group.add_widget (software_grid); + + var description_grid = new Gtk.Grid (); + description_grid.halign = Gtk.Align.CENTER; + description_grid.valign = Gtk.Align.CENTER; + description_grid.vexpand = true; + description_grid.column_spacing = 24; + description_grid.margin_start = 12; + description_grid.margin_end = 12; + description_grid.add (software_grid); + description_grid.add (new Gtk.Separator (Gtk.Orientation.VERTICAL)); + description_grid.add (hardware_view); + + add (description_grid); + add (button_grid); + show_all (); + } + + private void launch_support_url () { + try { + AppInfo.launch_default_for_uri (support_url, null); + } catch (Error e) { + critical (e.message); + } + } + + /** + * returns true to continue, false to cancel + */ + private bool confirm_restore_action () { + var dialog = new Granite.MessageDialog.with_image_from_icon_name ( + _("System Settings Will Be Restored to The Factory Defaults"), + _("All system settings and data will be reset to the default values. Personal data, such as music and pictures, will be unaffected."), + "dialog-warning", + Gtk.ButtonsType.CANCEL + ); + dialog.transient_for = (Gtk.Window) get_toplevel (); + + var continue_button = dialog.add_button (_("Restore Settings"), Gtk.ResponseType.ACCEPT); + continue_button.get_style_context ().add_class (Gtk.STYLE_CLASS_DESTRUCTIVE_ACTION); + + var result = dialog.run (); + dialog.destroy (); + + return result == Gtk.ResponseType.ACCEPT; + } + + private void settings_restore_clicked () { + if (confirm_restore_action ()) { + var all_schemas = get_pantheon_schemas (); + + foreach (var schema in all_schemas) { + reset_recursively (schema); + } + } + } + + private static void reset_all_keys (GLib.Settings settings) { + var schema = SettingsSchemaSource.get_default ().lookup ( + settings.schema_id, + true + ); + + foreach (var key in schema.list_keys ()) { + settings.reset (key); + } + } + + private static string[] get_pantheon_schemas () { + string[] schemas = {}; + string[] pantheon_schemas = {}; + string[] prefixes = { + "org.pantheon.desktop", + "io.elementary.desktop", + "io.elementary.onboarding", + "org.gnome.desktop", + "org.gnome.settings-daemon" + }; + + var sss = SettingsSchemaSource.get_default (); + + sss.list_schemas (true, out schemas, null); + + foreach (var schema in schemas) { + foreach (var prefix in prefixes) { + if (schema.has_prefix (prefix)) { + pantheon_schemas += schema; + } + } + } + return pantheon_schemas; + } + + private static void reset_recursively (string schema) { + var settings = new GLib.Settings (schema); + // change into delay mode + // so changes take place when apply () is called + settings.delay (); + + reset_all_keys (settings); + + foreach (var child in settings.list_children ()) { + var child_settings = settings.get_child (child); + + reset_all_keys (child_settings); + } + settings.apply (); + GLib.Settings.sync (); + } +} \ No newline at end of file diff --git a/src/meson.build b/src/meson.build index 08595f9f6..eb639cc70 100644 --- a/src/meson.build +++ b/src/meson.build @@ -3,7 +3,9 @@ plug_files = files( 'Objects/Device.vala', 'Interfaces/FwupdManager.vala', 'Utils/ARMPartDecoder.vala', - 'Views/HardwareView.vala' + 'Views/FirmwareView.vala', + 'Views/HardwareView.vala', + 'Views/SystemView.vala' ) switchboard_dep = dependency('switchboard-2.0') From 8957080d014e578cd4cb6842f0cf76c7ff519e28 Mon Sep 17 00:00:00 2001 From: Marius Meisenzahl Date: Fri, 11 Dec 2020 18:35:19 +0100 Subject: [PATCH 05/96] Add view for firmware devices --- src/Views/FirmwareDevicePage.vala | 55 +++++++++++++++++++++++++++++++ src/Views/FirmwareView.vala | 41 ++++++++++++++++++++--- src/Views/HardwareView.vala | 5 --- src/Views/SystemView.vala | 23 ++++++++++++- src/meson.build | 1 + 5 files changed, 114 insertions(+), 11 deletions(-) create mode 100644 src/Views/FirmwareDevicePage.vala diff --git a/src/Views/FirmwareDevicePage.vala b/src/Views/FirmwareDevicePage.vala new file mode 100644 index 000000000..6953e9f1d --- /dev/null +++ b/src/Views/FirmwareDevicePage.vala @@ -0,0 +1,55 @@ +/* +* Copyright (c) 2020 elementary, Inc. (https://elementary.io) +* +* 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 3 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 +* +* Authored by: Marius Meisenzahl +*/ + +public class About.FirmwareDevicePage : Granite.SettingsPage { + public FirmwareDevicePage (Device device) { + Object ( + display_widget: new Gtk.Image () { + gicon = new ThemedIcon (device.icon), + pixel_size = 32 + }, + status: device.summary, + title: device.name + ); + } + + construct { + var title_label = new Gtk.Label ("Title:"); + title_label.xalign = 1; + + var title_entry = new Gtk.Entry (); + title_entry.hexpand = true; + title_entry.placeholder_text = "This page's title"; + + var content_area = new Gtk.Grid (); + content_area.column_spacing = 12; + content_area.row_spacing = 12; + content_area.margin = 12; + content_area.attach (title_label, 0, 1, 1, 1); + content_area.attach (title_entry, 1, 1, 1, 1); + + add (content_area); + + title_entry.changed.connect (() => { + title = title_entry.text; + }); + } +} diff --git a/src/Views/FirmwareView.vala b/src/Views/FirmwareView.vala index 7c67bb925..bbc1e91d2 100644 --- a/src/Views/FirmwareView.vala +++ b/src/Views/FirmwareView.vala @@ -1,7 +1,38 @@ -public class About.FirmwareView : Gtk.Grid { +/* +* Copyright (c) 2020 elementary, Inc. (https://elementary.io) +* +* 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 3 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 +* +* Authored by: Marius Meisenzahl +*/ + +public class About.FirmwareView : Gtk.Paned { construct { - column_spacing = 12; - row_spacing = 24; - halign = Gtk.Align.CENTER; + var stack = new Gtk.Stack (); + + var fwupd_manager = FwupdManager.get_instance (); + foreach (var device in fwupd_manager.get_devices ()) { + var page = new FirmwareDevicePage (device); + + stack.add_named (page, device.id); + } + + var settings_sidebar = new Granite.SettingsSidebar (stack); + + add (settings_sidebar); + add (stack); } -} \ No newline at end of file +} diff --git a/src/Views/HardwareView.vala b/src/Views/HardwareView.vala index b7c1356b2..8b3fb9842 100644 --- a/src/Views/HardwareView.vala +++ b/src/Views/HardwareView.vala @@ -52,11 +52,6 @@ public class About.HardwareView : Gtk.Grid { critical (e.message); } - var fwupd_manager = FwupdManager.get_instance (); - foreach (var device in fwupd_manager.get_devices ()) { - print ("%s\n", device.to_string ()); - } - var manufacturer_logo = new Gtk.Image (); manufacturer_logo.icon_name = system_interface.icon_name; manufacturer_logo.hexpand = true; diff --git a/src/Views/SystemView.vala b/src/Views/SystemView.vala index 5ad6d4d08..8475efd1f 100644 --- a/src/Views/SystemView.vala +++ b/src/Views/SystemView.vala @@ -1,3 +1,24 @@ +/* +* Copyright (c) 2020 elementary, Inc. (https://elementary.io) +* +* 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 3 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 +* +* Authored by: Marius Meisenzahl +*/ + public class About.SystemView : Gtk.Grid { private string kernel_version; private string support_url; @@ -287,4 +308,4 @@ public class About.SystemView : Gtk.Grid { settings.apply (); GLib.Settings.sync (); } -} \ No newline at end of file +} diff --git a/src/meson.build b/src/meson.build index eb639cc70..da7b5abb3 100644 --- a/src/meson.build +++ b/src/meson.build @@ -3,6 +3,7 @@ plug_files = files( 'Objects/Device.vala', 'Interfaces/FwupdManager.vala', 'Utils/ARMPartDecoder.vala', + 'Views/FirmwareDevicePage.vala', 'Views/FirmwareView.vala', 'Views/HardwareView.vala', 'Views/SystemView.vala' From e73558c8d9534e8aeb196adacf81dd8399f5f459 Mon Sep 17 00:00:00 2001 From: Marius Meisenzahl Date: Fri, 11 Dec 2020 19:38:16 +0100 Subject: [PATCH 06/96] Add more information to view --- src/Interfaces/FwupdManager.vala | 12 +++++ src/Objects/Device.vala | 4 ++ src/Views/FirmwareDevicePage.vala | 85 +++++++++++++++++++++++-------- 3 files changed, 81 insertions(+), 20 deletions(-) diff --git a/src/Interfaces/FwupdManager.vala b/src/Interfaces/FwupdManager.vala index 9f3fcb21c..f70b35a14 100644 --- a/src/Interfaces/FwupdManager.vala +++ b/src/Interfaces/FwupdManager.vala @@ -59,10 +59,22 @@ public class About.FwupdManager : Object { case "Summary": device.summary = _device.lookup (key).get_string (); break; + case "Vendor": + device.vendor = _device.lookup (key).get_string (); + break; + case "Version": + device.version = _device.lookup (key).get_string (); + break; case "Icon": var icons = _device.lookup (key).get_strv (); device.icon = icons.length > 0 ? icons[0] : "unknown"; break; + case "Guid": + device.guids = _device.lookup (key).get_strv (); + break; + case "Flags": + device.flags = _device.lookup (key).get_uint64 (); + break; default: break; } diff --git a/src/Objects/Device.vala b/src/Objects/Device.vala index be773b349..18ee86b2f 100644 --- a/src/Objects/Device.vala +++ b/src/Objects/Device.vala @@ -24,6 +24,10 @@ public class About.Device : Object { public string name { get; set; } public string summary { get; set; } public string icon { get; set; } + public string vendor { get; set; } + public string version { get; set; } + public string[] guids { get; set; } + public uint64 flags { get; set; } public string to_string () { return "{id: %s, name: %s, icon: %s, summary: %s}".printf ( diff --git a/src/Views/FirmwareDevicePage.vala b/src/Views/FirmwareDevicePage.vala index 6953e9f1d..00a03ab79 100644 --- a/src/Views/FirmwareDevicePage.vala +++ b/src/Views/FirmwareDevicePage.vala @@ -19,37 +19,82 @@ * Authored by: Marius Meisenzahl */ -public class About.FirmwareDevicePage : Granite.SettingsPage { +public class About.FirmwareDevicePage : Granite.SimpleSettingsPage { + private Gtk.Label version_value_label; + private Gtk.Label vendor_value_label; + private Gtk.Grid guids_grid; + private Gtk.Label flags_value_label; + public FirmwareDevicePage (Device device) { + Object ( - display_widget: new Gtk.Image () { - gicon = new ThemedIcon (device.icon), - pixel_size = 32 - }, + icon_name: device.icon, status: device.summary, title: device.name ); + + version_value_label.label = device.version; + vendor_value_label.label = device.vendor; + foreach (var guid in device.guids) { + var label = new Gtk.Label (guid) { + xalign = 0, + hexpand = true + }; + guids_grid.add (label); + } + flags_value_label.label = "%llu".printf (device.flags); } construct { - var title_label = new Gtk.Label ("Title:"); - title_label.xalign = 1; + var version_label = new Gtk.Label (_("Current Version:")) { + xalign = 1 + }; + + version_value_label = new Gtk.Label ("") { + xalign = 0, + hexpand = true + }; + + var vendor_label = new Gtk.Label (_("Vendor:")) { + xalign = 1 + }; + + vendor_value_label = new Gtk.Label ("") { + xalign = 0, + hexpand = true + }; + + var guids_label = new Gtk.Label (_("GUIDs:")) { + xalign = 1, + yalign = 0 + }; + + guids_grid = new Gtk.Grid () { + orientation = Gtk.Orientation.VERTICAL + }; + + var flags_label = new Gtk.Label (_("Flags:")) { + xalign = 1 + }; - var title_entry = new Gtk.Entry (); - title_entry.hexpand = true; - title_entry.placeholder_text = "This page's title"; + flags_value_label = new Gtk.Label ("") { + xalign = 0, + hexpand = true + }; - var content_area = new Gtk.Grid (); - content_area.column_spacing = 12; - content_area.row_spacing = 12; - content_area.margin = 12; - content_area.attach (title_label, 0, 1, 1, 1); - content_area.attach (title_entry, 1, 1, 1, 1); + content_area.attach (version_label, 0, 1, 1, 1); + content_area.attach (version_value_label, 1, 1, 1, 1); + content_area.attach (vendor_label, 0, 2, 1, 1); + content_area.attach (vendor_value_label, 1, 2, 1, 1); + content_area.attach (guids_label, 0, 3, 1, 1); + content_area.attach (guids_grid, 1, 3, 1, 1); + content_area.attach (flags_label, 0, 4, 1, 1); + content_area.attach (flags_value_label, 1, 4, 1, 1); - add (content_area); + var verify_button = new Gtk.Button.with_label (_("Verify")); + var show_releases_button = new Gtk.Button.with_label (_("Show Releases")); - title_entry.changed.connect (() => { - title = title_entry.text; - }); + action_area.add (verify_button); + action_area.add (show_releases_button); } } From 39ac81843cc57ccd3ed3793ba83e5ad11f4307b7 Mon Sep 17 00:00:00 2001 From: Marius Meisenzahl Date: Fri, 11 Dec 2020 19:55:29 +0100 Subject: [PATCH 07/96] Add function of verify button --- src/Interfaces/FwupdManager.vala | 15 +++++++++++++-- src/Views/FirmwareDevicePage.vala | 11 ++++++++--- 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/src/Interfaces/FwupdManager.vala b/src/Interfaces/FwupdManager.vala index f70b35a14..d5f9b0bc7 100644 --- a/src/Interfaces/FwupdManager.vala +++ b/src/Interfaces/FwupdManager.vala @@ -26,6 +26,9 @@ public interface About.FwupdInterface : Object { [DBus (name = "GetDevices")] public abstract GLib.HashTable[] get_devices () throws GLib.Error; + + [DBus (name = "Verify")] + public abstract void verify (string id) throws GLib.Error; } public class About.FwupdManager : Object { @@ -82,17 +85,25 @@ public class About.FwupdManager : Object { devices_list.append (device); } } catch (Error e) { - warning ("Could not connect to color interface: %s", e.message); + warning ("Could not connect to fwupd interface: %s", e.message); } return devices_list; } + public void verify (string id) { + try { + interface.verify (id); + } catch (Error e) { + warning ("Could not connect to fwupd interface: %s", e.message); + } + } + construct { try { interface = Bus.get_proxy_sync (BusType.SYSTEM, "org.freedesktop.fwupd", "/"); } catch (Error e) { - warning ("Could not connect to color interface: %s", e.message); + warning ("Could not connect to fwupd interface: %s", e.message); } } } diff --git a/src/Views/FirmwareDevicePage.vala b/src/Views/FirmwareDevicePage.vala index 00a03ab79..a2faa2a12 100644 --- a/src/Views/FirmwareDevicePage.vala +++ b/src/Views/FirmwareDevicePage.vala @@ -24,9 +24,10 @@ public class About.FirmwareDevicePage : Granite.SimpleSettingsPage { private Gtk.Label vendor_value_label; private Gtk.Grid guids_grid; private Gtk.Label flags_value_label; + private Gtk.Button verify_button; + private Gtk.Button show_releases_button; public FirmwareDevicePage (Device device) { - Object ( icon_name: device.icon, status: device.summary, @@ -43,6 +44,10 @@ public class About.FirmwareDevicePage : Granite.SimpleSettingsPage { guids_grid.add (label); } flags_value_label.label = "%llu".printf (device.flags); + + verify_button.clicked.connect (() => { + FwupdManager.get_instance ().verify (device.id); + }); } construct { @@ -91,8 +96,8 @@ public class About.FirmwareDevicePage : Granite.SimpleSettingsPage { content_area.attach (flags_label, 0, 4, 1, 1); content_area.attach (flags_value_label, 1, 4, 1, 1); - var verify_button = new Gtk.Button.with_label (_("Verify")); - var show_releases_button = new Gtk.Button.with_label (_("Show Releases")); + verify_button = new Gtk.Button.with_label (_("Verify")); + show_releases_button = new Gtk.Button.with_label (_("Show Releases")); action_area.add (verify_button); action_area.add (show_releases_button); From 23e9f46989fb488f32d0a16b768d67559c26a2b0 Mon Sep 17 00:00:00 2001 From: Marius Meisenzahl Date: Fri, 11 Dec 2020 20:26:11 +0100 Subject: [PATCH 08/96] Add function to get releases --- src/Interfaces/FwupdManager.vala | 26 +++++++++++++++++++------- src/Objects/Release.vala | 22 ++++++++++++++++++++++ src/Views/FirmwareDevicePage.vala | 16 +++++++++++++++- src/meson.build | 1 + 4 files changed, 57 insertions(+), 8 deletions(-) create mode 100644 src/Objects/Release.vala diff --git a/src/Interfaces/FwupdManager.vala b/src/Interfaces/FwupdManager.vala index d5f9b0bc7..2c5064dfd 100644 --- a/src/Interfaces/FwupdManager.vala +++ b/src/Interfaces/FwupdManager.vala @@ -25,10 +25,13 @@ public interface About.FwupdInterface : Object { public abstract string host_product { owned get; } [DBus (name = "GetDevices")] - public abstract GLib.HashTable[] get_devices () throws GLib.Error; + public abstract HashTable[] get_devices () throws Error; + + [DBus (name = "GetReleases")] + public abstract HashTable[] get_releases (string id) throws Error; [DBus (name = "Verify")] - public abstract void verify (string id) throws GLib.Error; + public abstract void verify (string id) throws Error; } public class About.FwupdManager : Object { @@ -91,12 +94,21 @@ public class About.FwupdManager : Object { return devices_list; } - public void verify (string id) { - try { - interface.verify (id); - } catch (Error e) { - warning ("Could not connect to fwupd interface: %s", e.message); + public List get_releases (string id) throws Error { + var releases_list = new List (); + + foreach (var _release in interface.get_releases (id)) { + var release = new Release (); + foreach (var key in _release.get_keys ()) { + } + releases_list.append (release); } + + return releases_list; + } + + public void verify (string id) throws Error { + interface.verify (id); } construct { diff --git a/src/Objects/Release.vala b/src/Objects/Release.vala new file mode 100644 index 000000000..f230687ac --- /dev/null +++ b/src/Objects/Release.vala @@ -0,0 +1,22 @@ +/* +* Copyright (c) 2020 elementary, Inc. (https://elementary.io) +* +* 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 3 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 +* +* Authored by: Marius Meisenzahl +*/ + +public class About.Release : Object {} diff --git a/src/Views/FirmwareDevicePage.vala b/src/Views/FirmwareDevicePage.vala index a2faa2a12..4c26b5d1e 100644 --- a/src/Views/FirmwareDevicePage.vala +++ b/src/Views/FirmwareDevicePage.vala @@ -46,7 +46,21 @@ public class About.FirmwareDevicePage : Granite.SimpleSettingsPage { flags_value_label.label = "%llu".printf (device.flags); verify_button.clicked.connect (() => { - FwupdManager.get_instance ().verify (device.id); + try { + FwupdManager.get_instance ().verify (device.id); + } catch (Error e) { + // TODO show Granite.MessageDialog + warning ("Could not verify '%s': %s", device.id, e.message); + } + }); + + show_releases_button.clicked.connect (() => { + try { + FwupdManager.get_instance ().get_releases (device.id); + } catch (Error e) { + // TODO show Granite.MessageDialog + warning ("Could not get releases of '%s': %s", device.id, e.message); + } }); } diff --git a/src/meson.build b/src/meson.build index da7b5abb3..dc31423df 100644 --- a/src/meson.build +++ b/src/meson.build @@ -1,6 +1,7 @@ plug_files = files( 'Plug.vala', 'Objects/Device.vala', + 'Objects/Release.vala', 'Interfaces/FwupdManager.vala', 'Utils/ARMPartDecoder.vala', 'Views/FirmwareDevicePage.vala', From a3e9647ba30964b0bd0b56d215f84a2bac93e45c Mon Sep 17 00:00:00 2001 From: Marius Meisenzahl Date: Fri, 11 Dec 2020 20:38:20 +0100 Subject: [PATCH 09/96] Add page for releases --- src/Objects/Device.vala | 9 ------- src/Objects/Release.vala | 7 ++++- src/Views/FirmwareReleasePage.vala | 32 ++++++++++++++++++++++ src/Views/FirmwareReleasesView.vala | 41 +++++++++++++++++++++++++++++ src/meson.build | 2 ++ 5 files changed, 81 insertions(+), 10 deletions(-) create mode 100644 src/Views/FirmwareReleasePage.vala create mode 100644 src/Views/FirmwareReleasesView.vala diff --git a/src/Objects/Device.vala b/src/Objects/Device.vala index 18ee86b2f..838ecb45a 100644 --- a/src/Objects/Device.vala +++ b/src/Objects/Device.vala @@ -28,13 +28,4 @@ public class About.Device : Object { public string version { get; set; } public string[] guids { get; set; } public uint64 flags { get; set; } - - public string to_string () { - return "{id: %s, name: %s, icon: %s, summary: %s}".printf ( - id, - name, - icon, - summary - ); - } } diff --git a/src/Objects/Release.vala b/src/Objects/Release.vala index f230687ac..82f526cee 100644 --- a/src/Objects/Release.vala +++ b/src/Objects/Release.vala @@ -19,4 +19,9 @@ * Authored by: Marius Meisenzahl */ -public class About.Release : Object {} +public class About.Release : Object { + public string id { get; set; } + public string name { get; set; } + public string summary { get; set; } + public string icon { get; set; } +} diff --git a/src/Views/FirmwareReleasePage.vala b/src/Views/FirmwareReleasePage.vala new file mode 100644 index 000000000..9de0d61a3 --- /dev/null +++ b/src/Views/FirmwareReleasePage.vala @@ -0,0 +1,32 @@ +/* +* Copyright (c) 2020 elementary, Inc. (https://elementary.io) +* +* 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 3 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 +* +* Authored by: Marius Meisenzahl +*/ + +public class About.FirmwareReleasePage : Granite.SimpleSettingsPage { + public FirmwareReleasePage (Release release) { + Object ( + icon_name: release.icon, + status: release.summary, + title: release.name + ); + } + + construct {} +} diff --git a/src/Views/FirmwareReleasesView.vala b/src/Views/FirmwareReleasesView.vala new file mode 100644 index 000000000..cb7bb24f0 --- /dev/null +++ b/src/Views/FirmwareReleasesView.vala @@ -0,0 +1,41 @@ +/* +* Copyright (c) 2020 elementary, Inc. (https://elementary.io) +* +* 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 3 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 +* +* Authored by: Marius Meisenzahl +*/ + +public class About.FirmwareReleasesView : Gtk.Paned { + private Gtk.Stack stack; + + public FirmwareReleasesView (Release[] releases) { + foreach (var release in releases) { + var page = new FirmwareReleasePage (release); + + stack.add_named (page, release.id); + } + } + + construct { + stack = new Gtk.Stack (); + + var settings_sidebar = new Granite.SettingsSidebar (stack); + + add (settings_sidebar); + add (stack); + } +} diff --git a/src/meson.build b/src/meson.build index dc31423df..e1711881a 100644 --- a/src/meson.build +++ b/src/meson.build @@ -5,6 +5,8 @@ plug_files = files( 'Interfaces/FwupdManager.vala', 'Utils/ARMPartDecoder.vala', 'Views/FirmwareDevicePage.vala', + 'Views/FirmwareReleasePage.vala', + 'Views/FirmwareReleasesView.vala', 'Views/FirmwareView.vala', 'Views/HardwareView.vala', 'Views/SystemView.vala' From 60c094c4ae11244be693653b54e3eb10f2031dbb Mon Sep 17 00:00:00 2001 From: Marius Meisenzahl Date: Fri, 11 Dec 2020 21:12:07 +0100 Subject: [PATCH 10/96] Add reference on how to decode device flags --- src/Objects/Device.vala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Objects/Device.vala b/src/Objects/Device.vala index 838ecb45a..db2dc4227 100644 --- a/src/Objects/Device.vala +++ b/src/Objects/Device.vala @@ -27,5 +27,5 @@ public class About.Device : Object { public string vendor { get; set; } public string version { get; set; } public string[] guids { get; set; } - public uint64 flags { get; set; } + public uint64 flags { get; set; } // https://github.com/fwupd/fwupd/blob/72df1147933de747312aa7c9892f07e7916b8a39/libfwupd/fwupd-enums.h#L133 } From d9d69a705e7c6ea5d5def1d29f2ae5ba27c19ad2 Mon Sep 17 00:00:00 2001 From: Marius Meisenzahl Date: Tue, 22 Dec 2020 20:14:44 +0100 Subject: [PATCH 11/96] Check if releases are available for device --- src/Interfaces/FwupdManager.vala | 3 +++ src/Objects/Device.vala | 1 + src/Views/FirmwareDevicePage.vala | 5 +++++ 3 files changed, 9 insertions(+) diff --git a/src/Interfaces/FwupdManager.vala b/src/Interfaces/FwupdManager.vala index 2c5064dfd..cf962bac3 100644 --- a/src/Interfaces/FwupdManager.vala +++ b/src/Interfaces/FwupdManager.vala @@ -81,6 +81,9 @@ public class About.FwupdManager : Object { case "Flags": device.flags = _device.lookup (key).get_uint64 (); break; + case "InstallDuration": + device.install_duration = _device.lookup (key).get_uint64 (); + break; default: break; } diff --git a/src/Objects/Device.vala b/src/Objects/Device.vala index db2dc4227..1a13408a9 100644 --- a/src/Objects/Device.vala +++ b/src/Objects/Device.vala @@ -28,4 +28,5 @@ public class About.Device : Object { public string version { get; set; } public string[] guids { get; set; } public uint64 flags { get; set; } // https://github.com/fwupd/fwupd/blob/72df1147933de747312aa7c9892f07e7916b8a39/libfwupd/fwupd-enums.h#L133 + public uint64? install_duration { get; set; } } diff --git a/src/Views/FirmwareDevicePage.vala b/src/Views/FirmwareDevicePage.vala index 4c26b5d1e..12c85b2ee 100644 --- a/src/Views/FirmwareDevicePage.vala +++ b/src/Views/FirmwareDevicePage.vala @@ -45,6 +45,11 @@ public class About.FirmwareDevicePage : Granite.SimpleSettingsPage { } flags_value_label.label = "%llu".printf (device.flags); + if (device.install_duration == null) { + verify_button.sensitive = false; + show_releases_button.sensitive = false; + } + verify_button.clicked.connect (() => { try { FwupdManager.get_instance ().verify (device.id); From 6168c64aa183e1c418710a441916c3df4471e521 Mon Sep 17 00:00:00 2001 From: Marius Meisenzahl Date: Tue, 22 Dec 2020 20:18:08 +0100 Subject: [PATCH 12/96] Get releases --- src/Interfaces/FwupdManager.vala | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/src/Interfaces/FwupdManager.vala b/src/Interfaces/FwupdManager.vala index cf962bac3..e2fa0213e 100644 --- a/src/Interfaces/FwupdManager.vala +++ b/src/Interfaces/FwupdManager.vala @@ -99,14 +99,28 @@ public class About.FwupdManager : Object { public List get_releases (string id) throws Error { var releases_list = new List (); - + foreach (var _release in interface.get_releases (id)) { var release = new Release (); + release.icon = "security-high"; foreach (var key in _release.get_keys ()) { + switch (key) { + case "Filename": + release.id = _release.lookup (key).get_string (); + break; + case "Name": + release.name = _release.lookup (key).get_string (); + break; + case "Summary": + release.summary = _release.lookup (key).get_string (); + break; + default: + break; + } } releases_list.append (release); } - + return releases_list; } From 8d88c777725fad49b6b09ce0fa2a781303cc4aab Mon Sep 17 00:00:00 2001 From: Marius Meisenzahl Date: Tue, 22 Dec 2020 20:44:22 +0100 Subject: [PATCH 13/96] Show list of releases --- src/Interfaces/FwupdManager.vala | 5 +++ src/Views/FirmwareDevicePage.vala | 17 +++-------- src/Views/FirmwareDevicesView.vala | 47 +++++++++++++++++++++++++++++ src/Views/FirmwareReleasesView.vala | 21 ++++++++----- src/Views/FirmwareView.vala | 23 ++++++-------- src/meson.build | 1 + 6 files changed, 81 insertions(+), 33 deletions(-) create mode 100644 src/Views/FirmwareDevicesView.vala diff --git a/src/Interfaces/FwupdManager.vala b/src/Interfaces/FwupdManager.vala index e2fa0213e..61a9de435 100644 --- a/src/Interfaces/FwupdManager.vala +++ b/src/Interfaces/FwupdManager.vala @@ -68,6 +68,11 @@ public class About.FwupdManager : Object { case "Vendor": device.vendor = _device.lookup (key).get_string (); break; + case "VendorId": + if (device.vendor == null) { + device.vendor = _device.lookup (key).get_string (); + } + break; case "Version": device.version = _device.lookup (key).get_string (); break; diff --git a/src/Views/FirmwareDevicePage.vala b/src/Views/FirmwareDevicePage.vala index 12c85b2ee..61ae1e5e6 100644 --- a/src/Views/FirmwareDevicePage.vala +++ b/src/Views/FirmwareDevicePage.vala @@ -27,6 +27,9 @@ public class About.FirmwareDevicePage : Granite.SimpleSettingsPage { private Gtk.Button verify_button; private Gtk.Button show_releases_button; + public signal void verify (string device_id); + public signal void show_releases (string device_id); + public FirmwareDevicePage (Device device) { Object ( icon_name: device.icon, @@ -51,21 +54,11 @@ public class About.FirmwareDevicePage : Granite.SimpleSettingsPage { } verify_button.clicked.connect (() => { - try { - FwupdManager.get_instance ().verify (device.id); - } catch (Error e) { - // TODO show Granite.MessageDialog - warning ("Could not verify '%s': %s", device.id, e.message); - } + verify (device.id); }); show_releases_button.clicked.connect (() => { - try { - FwupdManager.get_instance ().get_releases (device.id); - } catch (Error e) { - // TODO show Granite.MessageDialog - warning ("Could not get releases of '%s': %s", device.id, e.message); - } + show_releases (device.id); }); } diff --git a/src/Views/FirmwareDevicesView.vala b/src/Views/FirmwareDevicesView.vala new file mode 100644 index 000000000..bd4f45c6a --- /dev/null +++ b/src/Views/FirmwareDevicesView.vala @@ -0,0 +1,47 @@ +/* +* Copyright (c) 2020 elementary, Inc. (https://elementary.io) +* +* 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 3 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 +* +* Authored by: Marius Meisenzahl +*/ + +public class About.FirmwareDevicesView : Gtk.Paned { + public signal void verify (string device_id); + public signal void show_releases (string device_id); + + construct { + var stack = new Gtk.Stack (); + + var fwupd_manager = FwupdManager.get_instance (); + foreach (var device in fwupd_manager.get_devices ()) { + var page = new FirmwareDevicePage (device); + page.verify.connect ((device_id) => { + verify (device_id); + }); + page.show_releases.connect ((device_id) => { + show_releases (device_id); + }); + + stack.add_named (page, device.id); + } + + var settings_sidebar = new Granite.SettingsSidebar (stack); + + add (settings_sidebar); + add (stack); + } +} diff --git a/src/Views/FirmwareReleasesView.vala b/src/Views/FirmwareReleasesView.vala index cb7bb24f0..e91671ed2 100644 --- a/src/Views/FirmwareReleasesView.vala +++ b/src/Views/FirmwareReleasesView.vala @@ -22,14 +22,6 @@ public class About.FirmwareReleasesView : Gtk.Paned { private Gtk.Stack stack; - public FirmwareReleasesView (Release[] releases) { - foreach (var release in releases) { - var page = new FirmwareReleasePage (release); - - stack.add_named (page, release.id); - } - } - construct { stack = new Gtk.Stack (); @@ -38,4 +30,17 @@ public class About.FirmwareReleasesView : Gtk.Paned { add (settings_sidebar); add (stack); } + + public void get_releases (string device_id) { + foreach (Gtk.Widget element in stack.get_children ()) { + stack.remove (element); + } + + var fwupd_manager = FwupdManager.get_instance (); + foreach (var release in fwupd_manager.get_releases (device_id)) { + var page = new FirmwareReleasePage (release); + + stack.add_named (page, release.id); + } + } } diff --git a/src/Views/FirmwareView.vala b/src/Views/FirmwareView.vala index bbc1e91d2..ddd08ebe8 100644 --- a/src/Views/FirmwareView.vala +++ b/src/Views/FirmwareView.vala @@ -19,20 +19,17 @@ * Authored by: Marius Meisenzahl */ -public class About.FirmwareView : Gtk.Paned { +public class About.FirmwareView : Gtk.Stack { construct { - var stack = new Gtk.Stack (); + var firmware_devices_view = new FirmwareDevicesView (); + var firmware_releases_view = new FirmwareReleasesView (); - var fwupd_manager = FwupdManager.get_instance (); - foreach (var device in fwupd_manager.get_devices ()) { - var page = new FirmwareDevicePage (device); + firmware_devices_view.show_releases.connect ((device_id) => { + firmware_releases_view.get_releases (device_id); + set_visible_child_name ("releases"); + }); - stack.add_named (page, device.id); - } - - var settings_sidebar = new Granite.SettingsSidebar (stack); - - add (settings_sidebar); - add (stack); + add_named (firmware_devices_view, "devices"); + add_named (firmware_releases_view, "releases"); } -} +} \ No newline at end of file diff --git a/src/meson.build b/src/meson.build index e1711881a..17160b499 100644 --- a/src/meson.build +++ b/src/meson.build @@ -5,6 +5,7 @@ plug_files = files( 'Interfaces/FwupdManager.vala', 'Utils/ARMPartDecoder.vala', 'Views/FirmwareDevicePage.vala', + 'Views/FirmwareDevicesView.vala', 'Views/FirmwareReleasePage.vala', 'Views/FirmwareReleasesView.vala', 'Views/FirmwareView.vala', From 82217a51d7fbc1b4881bdb28cfc9d5c8e5391a07 Mon Sep 17 00:00:00 2001 From: Marius Meisenzahl Date: Tue, 22 Dec 2020 21:09:02 +0100 Subject: [PATCH 14/96] Show install duration --- src/Interfaces/FwupdManager.vala | 2 +- src/Objects/Device.vala | 2 +- src/Views/FirmwareDevicePage.vala | 25 ++++++++++++++++++++++--- 3 files changed, 24 insertions(+), 5 deletions(-) diff --git a/src/Interfaces/FwupdManager.vala b/src/Interfaces/FwupdManager.vala index 61a9de435..8b5f461c5 100644 --- a/src/Interfaces/FwupdManager.vala +++ b/src/Interfaces/FwupdManager.vala @@ -87,7 +87,7 @@ public class About.FwupdManager : Object { device.flags = _device.lookup (key).get_uint64 (); break; case "InstallDuration": - device.install_duration = _device.lookup (key).get_uint64 (); + device.install_duration = _device.lookup (key).get_uint32 (); break; default: break; diff --git a/src/Objects/Device.vala b/src/Objects/Device.vala index 1a13408a9..b151b1056 100644 --- a/src/Objects/Device.vala +++ b/src/Objects/Device.vala @@ -28,5 +28,5 @@ public class About.Device : Object { public string version { get; set; } public string[] guids { get; set; } public uint64 flags { get; set; } // https://github.com/fwupd/fwupd/blob/72df1147933de747312aa7c9892f07e7916b8a39/libfwupd/fwupd-enums.h#L133 - public uint64? install_duration { get; set; } + public uint32 install_duration { get; set; } } diff --git a/src/Views/FirmwareDevicePage.vala b/src/Views/FirmwareDevicePage.vala index 61ae1e5e6..e190e8426 100644 --- a/src/Views/FirmwareDevicePage.vala +++ b/src/Views/FirmwareDevicePage.vala @@ -26,6 +26,8 @@ public class About.FirmwareDevicePage : Granite.SimpleSettingsPage { private Gtk.Label flags_value_label; private Gtk.Button verify_button; private Gtk.Button show_releases_button; + private Gtk.Label install_duration_label; + private Gtk.Label install_duration_value_label; public signal void verify (string device_id); public signal void show_releases (string device_id); @@ -48,9 +50,15 @@ public class About.FirmwareDevicePage : Granite.SimpleSettingsPage { } flags_value_label.label = "%llu".printf (device.flags); - if (device.install_duration == null) { - verify_button.sensitive = false; - show_releases_button.sensitive = false; + verify_button.sensitive = device.install_duration > 0; + show_releases_button.sensitive = device.install_duration > 0; + install_duration_label.visible = device.install_duration > 0; + install_duration_value_label.visible = device.install_duration > 0; + + if (device.install_duration > 0) { + install_duration_value_label.label = "%lu s".printf (device.install_duration); + } else { + install_duration_value_label.label = ""; } verify_button.clicked.connect (() => { @@ -99,6 +107,15 @@ public class About.FirmwareDevicePage : Granite.SimpleSettingsPage { hexpand = true }; + install_duration_label = new Gtk.Label (_("Install Duration:")) { + xalign = 1 + }; + + install_duration_value_label = new Gtk.Label ("") { + xalign = 0, + hexpand = true + }; + content_area.attach (version_label, 0, 1, 1, 1); content_area.attach (version_value_label, 1, 1, 1, 1); content_area.attach (vendor_label, 0, 2, 1, 1); @@ -107,6 +124,8 @@ public class About.FirmwareDevicePage : Granite.SimpleSettingsPage { content_area.attach (guids_grid, 1, 3, 1, 1); content_area.attach (flags_label, 0, 4, 1, 1); content_area.attach (flags_value_label, 1, 4, 1, 1); + content_area.attach (install_duration_label, 0, 5, 1, 1); + content_area.attach (install_duration_value_label, 1, 5, 1, 1); verify_button = new Gtk.Button.with_label (_("Verify")); show_releases_button = new Gtk.Button.with_label (_("Show Releases")); From 18ad2abbf0b47e2dab0784804030673230f81d6c Mon Sep 17 00:00:00 2001 From: Marius Meisenzahl Date: Thu, 24 Dec 2020 06:34:31 +0100 Subject: [PATCH 15/96] Catch error --- src/Interfaces/FwupdManager.vala | 40 ++++++++++++++++++-------------- 1 file changed, 22 insertions(+), 18 deletions(-) diff --git a/src/Interfaces/FwupdManager.vala b/src/Interfaces/FwupdManager.vala index 8b5f461c5..3a15fe984 100644 --- a/src/Interfaces/FwupdManager.vala +++ b/src/Interfaces/FwupdManager.vala @@ -102,28 +102,32 @@ public class About.FwupdManager : Object { return devices_list; } - public List get_releases (string id) throws Error { + public List get_releases (string id) { var releases_list = new List (); - foreach (var _release in interface.get_releases (id)) { - var release = new Release (); - release.icon = "security-high"; - foreach (var key in _release.get_keys ()) { - switch (key) { - case "Filename": - release.id = _release.lookup (key).get_string (); - break; - case "Name": - release.name = _release.lookup (key).get_string (); - break; - case "Summary": - release.summary = _release.lookup (key).get_string (); - break; - default: - break; + try { + foreach (var _release in interface.get_releases (id)) { + var release = new Release (); + release.icon = "security-high"; + foreach (var key in _release.get_keys ()) { + switch (key) { + case "Filename": + release.id = _release.lookup (key).get_string (); + break; + case "Name": + release.name = _release.lookup (key).get_string (); + break; + case "Summary": + release.summary = _release.lookup (key).get_string (); + break; + default: + break; + } } + releases_list.append (release); } - releases_list.append (release); + } catch (Error e) { + warning ("Could not connect to fwupd interface: %s", e.message); } return releases_list; From 733573708f39c206b2f197f2cb0ca9669efc6149 Mon Sep 17 00:00:00 2001 From: Marius Meisenzahl Date: Thu, 24 Dec 2020 09:12:38 +0100 Subject: [PATCH 16/96] Decode device flags --- src/Objects/Device.vala | 2 +- src/Objects/DeviceFlag.vala | 164 ++++++++++++++++++++++++++++++++++++ 2 files changed, 165 insertions(+), 1 deletion(-) create mode 100644 src/Objects/DeviceFlag.vala diff --git a/src/Objects/Device.vala b/src/Objects/Device.vala index b151b1056..20e43a928 100644 --- a/src/Objects/Device.vala +++ b/src/Objects/Device.vala @@ -27,6 +27,6 @@ public class About.Device : Object { public string vendor { get; set; } public string version { get; set; } public string[] guids { get; set; } - public uint64 flags { get; set; } // https://github.com/fwupd/fwupd/blob/72df1147933de747312aa7c9892f07e7916b8a39/libfwupd/fwupd-enums.h#L133 + public uint64 flags { get; set; } public uint32 install_duration { get; set; } } diff --git a/src/Objects/DeviceFlag.vala b/src/Objects/DeviceFlag.vala new file mode 100644 index 000000000..c791a65be --- /dev/null +++ b/src/Objects/DeviceFlag.vala @@ -0,0 +1,164 @@ +/* +* Copyright (c) 2020 elementary, Inc. (https://elementary.io) +* +* 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 3 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 +* +* Authored by: Marius Meisenzahl +*/ + +// https://github.com/fwupd/fwupd/blob/72df1147933de747312aa7c9892f07e7916b8a39/libfwupd/fwupd-enums.h#L133 +enum About.DeviceFlag { + NONE = (0u), /* Since: 0.1.3 */ + INTERNAL = (1u << 0), /* Since: 0.1.3 */ + UPDATABLE = (1u << 1), /* Since: 0.9.7 */ + ONLY_OFFLINE = (1u << 2), /* Since: 0.9.7 */ + REQUIRE_AC = (1u << 3), /* Since: 0.6.3 */ + LOCKED = (1u << 4), /* Since: 0.6.3 */ + SUPPORTED = (1u << 5), /* Since: 0.7.1 */ + NEEDS_BOOTLOADER = (1u << 6), /* Since: 0.7.3 */ + REGISTERED = (1u << 7), /* Since: 0.9.7 */ + NEEDS_REBOOT = (1u << 8), /* Since: 0.9.7 */ + REPORTED = (1u << 9), /* Since: 1.0.4 */ + NOTIFIED = (1u << 10), /* Since: 1.0.5 */ + USE_RUNTIME_VERSION = (1u << 11), /* Since: 1.0.6 */ + INSTALL_PARENT_FIRST = (1u << 12), /* Since: 1.0.8 */ + IS_BOOTLOADER = (1u << 13), /* Since: 1.0.8 */ + WAIT_FOR_REPLUG = (1u << 14), /* Since: 1.1.2 */ + IGNORE_VALIDATION = (1u << 15), /* Since: 1.1.2 */ + TRUSTED = (1u << 16), /* Since: 1.1.2 */ + NEEDS_SHUTDOWN = (1u << 17), /* Since: 1.2.4 */ + ANOTHER_WRITE_REQUIRED = (1u << 18), /* Since: 1.2.5 */ + NO_AUTO_INSTANCE_IDS = (1u << 19), /* Since: 1.2.5 */ + NEEDS_ACTIVATION = (1u << 20), /* Since: 1.2.6 */ + ENSURE_SEMVER = (1u << 21), /* Since: 1.2.9 */ + HISTORICAL = (1u << 22), /* Since: 1.3.2 */ + ONLY_SUPPORTED = (1u << 23), /* Since: 1.3.3 */ + WILL_DISAPPEAR = (1u << 24), /* Since: 1.3.3 */ + CAN_VERIFY = (1u << 25), /* Since: 1.3.3 */ + CAN_VERIFY_IMAGE = (1u << 26), /* Since: 1.3.3 */ + DUAL_IMAGE = (1u << 27), /* Since: 1.3.3 */ + SELF_RECOVERY = (1u << 28), /* Since: 1.3.3 */ + USABLE_DURING_UPDATE = (1u << 29), /* Since: 1.3.3 */ + VERSION_CHECK_REQUIRED = (1u << 30), /* Since: 1.3.7 */ + INSTALL_ALL_RELEASES = (1u << 31), /* Since: 1.3.7 */ + MD_SET_NAME = (1u << 32), /* Since: 1.4.0 */ + MD_SET_NAME_CATEGORY = (1u << 33), /* Since: 1.4.0 */ + MD_SET_VERFMT = (1u << 34), /* Since: 1.4.0 */ + ADD_COUNTERPART_GUIDS = (1u << 35), /* Since: 1.4.0 */ + NO_GUID_MATCHING = (1u << 36), /* Since: 1.4.1 */ + UPDATABLE_HIDDEN = (1u << 37), /* Since: 1.4.1 */ + SKIPS_RESTART = (1u << 38), /* Since: 1.5.0 */ + HAS_MULTIPLE_BRANCHES = (1u << 39), /* Since: 1.5.0 */ + BACKUP_BEFORE_INSTALL = (1u << 40), /* Since: 1.5.0 */ + MD_SET_ICON = (1u << 41), /* Since: 1.5.2 */ + UNKNOWN = 18446744073709551615; /* Since: 0.7.3 */ // using uint64.max --> ‘MAX’ undeclared here (not in a function) + + // https://gitlab.gnome.org/hughsie/gnome-firmware-updater/-/blob/f5281078e3cfade7ff919c812ba63de22431aaf2/src/gfu-common.c#L249 + public string? to_string() { + switch (this) { + case NONE: + return null; + case INTERNAL: + /* TRANSLATORS: Device cannot be removed easily*/ + return _("Internal device"); + case UPDATABLE: + /* TRANSLATORS: Device is updatable in this or any other mode */ + return _("Updatable"); + case ONLY_OFFLINE: + /* TRANSLATORS: Update can only be done from offline mode */ + return _("Update requires a reboot"); + case REQUIRE_AC: + /* TRANSLATORS: Must be plugged in to an outlet */ + return _("System requires external power source"); + case LOCKED: + /* TRANSLATORS: Is locked and can be unlocked */ + return _("Device is locked"); + case SUPPORTED: + /* TRANSLATORS: Is found in current metadata */ + return _("Supported on LVFS"); + case NEEDS_BOOTLOADER: + /* TRANSLATORS: Requires a bootloader mode to be manually enabled by the user */ + return _("Requires a bootloader"); + case NEEDS_REBOOT: + /* TRANSLATORS: Requires a reboot to apply firmware or to reload hardware */ + return _("Needs a reboot after installation"); + case NEEDS_SHUTDOWN: + /* TRANSLATORS: Requires system shutdown to apply firmware */ + return _("Needs shutdown after installation"); + case REPORTED: + /* TRANSLATORS: Has been reported to a metadata server */ + return _("Reported to LVFS"); + case NOTIFIED: + /* TRANSLATORS: User has been notified */ + return _("User has been notified"); + case USE_RUNTIME_VERSION: + /* skip */ + return null; + case INSTALL_PARENT_FIRST: + /* TRANSLATORS: Install composite firmware on the parent before the child */ + return _("Install to parent device first"); + case IS_BOOTLOADER: + /* TRANSLATORS: Is currently in bootloader mode */ + return _("Is in bootloader mode"); + case WAIT_FOR_REPLUG: + /* TRANSLATORS: The hardware is waiting to be replugged */ + return _("Hardware is waiting to be replugged"); + case IGNORE_VALIDATION: + /* TRANSLATORS: Ignore validation safety checks when flashing this device */ + return _("Ignore validation safety checks"); + case ANOTHER_WRITE_REQUIRED: + /* skip */ + return null; + case NO_AUTO_INSTANCE_IDS: + /* skip */ + return null; + case NEEDS_ACTIVATION: + /* TRANSLATORS: Device update needs to be separately activated */ + return _("Device update needs activation"); + case ENSURE_SEMVER: + /* skip */ + return null; + case HISTORICAL: + /* skip */ + return null; + case ONLY_SUPPORTED: + /* skip */ + return null; + case WILL_DISAPPEAR: + /* TRANSLATORS: Device will not return after update completes */ + return _("Device will not re-appear after update completes"); + case CAN_VERIFY: + /* TRANSLATORS: Device supports some form of checksum verification */ + return _("Cryptographic hash verification is available"); + case CAN_VERIFY_IMAGE: + /* skip */ + return null; + case DUAL_IMAGE: + /* TRANSLATORS: Device supports a safety mechanism for flashing */ + return _("Device stages updates"); + case SELF_RECOVERY: + /* TRANSLATORS: Device supports a safety mechanism for flashing */ + return _("Device can recover flash failures"); + case USABLE_DURING_UPDATE: + /* TRANSLATORS: Device remains usable during update */ + return _("Device is usable for the duration of the update"); + case UNKNOWN: + return null; + default: + return null; + } + } +} From 691f150ac603129e7d767a3b31d7c137f2521f64 Mon Sep 17 00:00:00 2001 From: Marius Meisenzahl Date: Thu, 24 Dec 2020 10:03:34 +0100 Subject: [PATCH 17/96] Show icon and text for device flags --- src/Objects/DeviceFlag.vala | 201 +++++++++++++++++++++++++++++- src/Views/FirmwareDevicePage.vala | 38 ++++-- src/Views/FirmwareView.vala | 2 +- src/meson.build | 1 + 4 files changed, 233 insertions(+), 9 deletions(-) diff --git a/src/Objects/DeviceFlag.vala b/src/Objects/DeviceFlag.vala index c791a65be..fcb459d4c 100644 --- a/src/Objects/DeviceFlag.vala +++ b/src/Objects/DeviceFlag.vala @@ -20,7 +20,7 @@ */ // https://github.com/fwupd/fwupd/blob/72df1147933de747312aa7c9892f07e7916b8a39/libfwupd/fwupd-enums.h#L133 -enum About.DeviceFlag { +public enum About.DeviceFlag { NONE = (0u), /* Since: 0.1.3 */ INTERNAL = (1u << 0), /* Since: 0.1.3 */ UPDATABLE = (1u << 1), /* Since: 0.9.7 */ @@ -66,6 +66,145 @@ enum About.DeviceFlag { MD_SET_ICON = (1u << 41), /* Since: 1.5.2 */ UNKNOWN = 18446744073709551615; /* Since: 0.7.3 */ // using uint64.max --> ‘MAX’ undeclared here (not in a function) + public static List get_list (uint64 flags) { + var list = new List (); + + if ((flags & (0u)) > 0) { + list.append (DeviceFlag.NONE); + } + if ((flags & (1u << 0)) > 0) { + list.append (DeviceFlag.INTERNAL); + } + if ((flags & (1u << 1)) > 0) { + list.append (DeviceFlag.UPDATABLE); + } + if ((flags & (1u << 2)) > 0) { + list.append (DeviceFlag.ONLY_OFFLINE); + } + if ((flags & (1u << 3)) > 0) { + list.append (DeviceFlag.REQUIRE_AC); + } + if ((flags & (1u << 4)) > 0) { + list.append (DeviceFlag.LOCKED); + } + if ((flags & (1u << 5)) > 0) { + list.append (DeviceFlag.SUPPORTED); + } + if ((flags & (1u << 6)) > 0) { + list.append (DeviceFlag.NEEDS_BOOTLOADER); + } + if ((flags & (1u << 7)) > 0) { + list.append (DeviceFlag.REGISTERED); + } + if ((flags & (1u << 8)) > 0) { + list.append (DeviceFlag.NEEDS_REBOOT); + } + if ((flags & (1u << 9)) > 0) { + list.append (DeviceFlag.REPORTED); + } + if ((flags & (1u << 10)) > 0) { + list.append (DeviceFlag.NOTIFIED); + } + if ((flags & (1u << 11)) > 0) { + list.append (DeviceFlag.USE_RUNTIME_VERSION); + } + if ((flags & (1u << 12)) > 0) { + list.append (DeviceFlag.INSTALL_PARENT_FIRST); + } + if ((flags & (1u << 13)) > 0) { + list.append (DeviceFlag.IS_BOOTLOADER); + } + if ((flags & (1u << 14)) > 0) { + list.append (DeviceFlag.WAIT_FOR_REPLUG); + } + if ((flags & (1u << 15)) > 0) { + list.append (DeviceFlag.IGNORE_VALIDATION); + } + if ((flags & (1u << 16)) > 0) { + list.append (DeviceFlag.TRUSTED); + } + if ((flags & (1u << 17)) > 0) { + list.append (DeviceFlag.NEEDS_SHUTDOWN); + } + if ((flags & (1u << 18)) > 0) { + list.append (DeviceFlag.ANOTHER_WRITE_REQUIRED); + } + if ((flags & (1u << 19)) > 0) { + list.append (DeviceFlag.NO_AUTO_INSTANCE_IDS); + } + if ((flags & (1u << 20)) > 0) { + list.append (DeviceFlag.NEEDS_ACTIVATION); + } + if ((flags & (1u << 21)) > 0) { + list.append (DeviceFlag.ENSURE_SEMVER); + } + if ((flags & (1u << 22)) > 0) { + list.append (DeviceFlag.HISTORICAL); + } + if ((flags & (1u << 23)) > 0) { + list.append (DeviceFlag.ONLY_SUPPORTED); + } + if ((flags & (1u << 24)) > 0) { + list.append (DeviceFlag.WILL_DISAPPEAR); + } + if ((flags & (1u << 25)) > 0) { + list.append (DeviceFlag.CAN_VERIFY); + } + if ((flags & (1u << 26)) > 0) { + list.append (DeviceFlag.CAN_VERIFY_IMAGE); + } + if ((flags & (1u << 27)) > 0) { + list.append (DeviceFlag.DUAL_IMAGE); + } + if ((flags & (1u << 28)) > 0) { + list.append (DeviceFlag.SELF_RECOVERY); + } + if ((flags & (1u << 29)) > 0) { + list.append (DeviceFlag.USABLE_DURING_UPDATE); + } + if ((flags & (1u << 30)) > 0) { + list.append (DeviceFlag.VERSION_CHECK_REQUIRED); + } + if ((flags & (1u << 31)) > 0) { + list.append (DeviceFlag.INSTALL_ALL_RELEASES); + } + if ((flags & (1u << 32)) > 0) { + list.append (DeviceFlag.MD_SET_NAME); + } + if ((flags & (1u << 33)) > 0) { + list.append (DeviceFlag.MD_SET_NAME_CATEGORY); + } + if ((flags & (1u << 34)) > 0) { + list.append (DeviceFlag.MD_SET_VERFMT); + } + if ((flags & (1u << 35)) > 0) { + list.append (DeviceFlag.ADD_COUNTERPART_GUIDS); + } + if ((flags & (1u << 36)) > 0) { + list.append (DeviceFlag.NO_GUID_MATCHING); + } + if ((flags & (1u << 37)) > 0) { + list.append (DeviceFlag.UPDATABLE_HIDDEN); + } + if ((flags & (1u << 38)) > 0) { + list.append (DeviceFlag.SKIPS_RESTART); + } + if ((flags & (1u << 39)) > 0) { + list.append (DeviceFlag.HAS_MULTIPLE_BRANCHES); + } + if ((flags & (1u << 40)) > 0) { + list.append (DeviceFlag.BACKUP_BEFORE_INSTALL); + } + if ((flags & (1u << 41)) > 0) { + list.append (DeviceFlag.MD_SET_ICON); + } + if ((flags & (18446744073709551615)) > 0) { + list.append (DeviceFlag.UNKNOWN); + } + + return list; + } + // https://gitlab.gnome.org/hughsie/gnome-firmware-updater/-/blob/f5281078e3cfade7ff919c812ba63de22431aaf2/src/gfu-common.c#L249 public string? to_string() { switch (this) { @@ -161,4 +300,64 @@ enum About.DeviceFlag { return null; } } + + // https://gitlab.gnome.org/hughsie/gnome-firmware-updater/-/blob/f5281078e3cfade7ff919c812ba63de22431aaf2/src/gfu-common.c#L377 + public string to_icon () { + switch (this) { + case INTERNAL: + return "drive-harddisk-symbolic"; + case UPDATABLE: + return "software-update-available-symbolic"; + case ONLY_OFFLINE: + return "network-offline-symbolic"; + case REQUIRE_AC: + return "battery-symbolic"; + case LOCKED: + return "locked-symbolic"; + case SUPPORTED: + return "security-high-symbolic"; + case NEEDS_BOOTLOADER: + return "computer-symbolic"; + case NEEDS_REBOOT: + return "system-reboot-symbolic"; + case NEEDS_SHUTDOWN: + return "system-shutdown-symbolic"; + case REPORTED: + return "task-due-symbolic"; + case NOTIFIED: + return "task-due-symbolic"; + case USE_RUNTIME_VERSION: + return "system-run-symbolic"; + case INSTALL_PARENT_FIRST: + return "system-software-install-symbolic"; + case IS_BOOTLOADER: + return "computer-symbolic"; + case WAIT_FOR_REPLUG: + return "battery-low-symbolic"; + case IGNORE_VALIDATION: + return "dialog-error-symbolic"; + case ANOTHER_WRITE_REQUIRED: + return "media-floppy-symbolic"; + case NO_AUTO_INSTANCE_IDS: + return "dialog-error-symbolic"; + case NEEDS_ACTIVATION: + return "emblem-important-symbolic"; + case ENSURE_SEMVER: + return "emblem-important-symbolic"; + case WILL_DISAPPEAR: + return "emblem-important-symbolic"; + case CAN_VERIFY: + return "emblem-important-symbolic"; + case DUAL_IMAGE: + return "emblem-important-symbolic"; + case SELF_RECOVERY: + return "emblem-important-symbolic"; + case USABLE_DURING_UPDATE: + return "emblem-important-symbolic"; + case UNKNOWN: + return "unknown-symbolic"; + default: + return "unknown-symbolic"; + } + } } diff --git a/src/Views/FirmwareDevicePage.vala b/src/Views/FirmwareDevicePage.vala index e190e8426..84dc49d06 100644 --- a/src/Views/FirmwareDevicePage.vala +++ b/src/Views/FirmwareDevicePage.vala @@ -23,7 +23,7 @@ public class About.FirmwareDevicePage : Granite.SimpleSettingsPage { private Gtk.Label version_value_label; private Gtk.Label vendor_value_label; private Gtk.Grid guids_grid; - private Gtk.Label flags_value_label; + private Gtk.Grid flags_grid; private Gtk.Button verify_button; private Gtk.Button show_releases_button; private Gtk.Label install_duration_label; @@ -48,7 +48,30 @@ public class About.FirmwareDevicePage : Granite.SimpleSettingsPage { }; guids_grid.add (label); } - flags_value_label.label = "%llu".printf (device.flags); + + foreach (var device_flag in DeviceFlag.get_list (device.flags)) { + var name = device_flag.to_string (); + + if (name != null) { + var icon = new Gtk.Image () { + gicon = new ThemedIcon (device_flag.to_icon ()), + pixel_size = 16 + }; + var label = new Gtk.Label (name) { + xalign = 0, + hexpand = true + }; + var grid = new Gtk.Grid () { + orientation = Gtk.Orientation.HORIZONTAL, + column_spacing = 8 + }; + + grid.add (icon); + grid.add (label); + + flags_grid.add (grid); + } + } verify_button.sensitive = device.install_duration > 0; show_releases_button.sensitive = device.install_duration > 0; @@ -99,12 +122,13 @@ public class About.FirmwareDevicePage : Granite.SimpleSettingsPage { }; var flags_label = new Gtk.Label (_("Flags:")) { - xalign = 1 + xalign = 1, + yalign = 0 }; - flags_value_label = new Gtk.Label ("") { - xalign = 0, - hexpand = true + flags_grid = new Gtk.Grid () { + orientation = Gtk.Orientation.VERTICAL, + row_spacing = 4 }; install_duration_label = new Gtk.Label (_("Install Duration:")) { @@ -123,7 +147,7 @@ public class About.FirmwareDevicePage : Granite.SimpleSettingsPage { content_area.attach (guids_label, 0, 3, 1, 1); content_area.attach (guids_grid, 1, 3, 1, 1); content_area.attach (flags_label, 0, 4, 1, 1); - content_area.attach (flags_value_label, 1, 4, 1, 1); + content_area.attach (flags_grid, 1, 4, 1, 1); content_area.attach (install_duration_label, 0, 5, 1, 1); content_area.attach (install_duration_value_label, 1, 5, 1, 1); diff --git a/src/Views/FirmwareView.vala b/src/Views/FirmwareView.vala index ddd08ebe8..011731880 100644 --- a/src/Views/FirmwareView.vala +++ b/src/Views/FirmwareView.vala @@ -32,4 +32,4 @@ public class About.FirmwareView : Gtk.Stack { add_named (firmware_devices_view, "devices"); add_named (firmware_releases_view, "releases"); } -} \ No newline at end of file +} diff --git a/src/meson.build b/src/meson.build index 17160b499..bcb133ac0 100644 --- a/src/meson.build +++ b/src/meson.build @@ -1,6 +1,7 @@ plug_files = files( 'Plug.vala', 'Objects/Device.vala', + 'Objects/DeviceFlag.vala', 'Objects/Release.vala', 'Interfaces/FwupdManager.vala', 'Utils/ARMPartDecoder.vala', From 2ca54666b7fed47d0c934fde69b470d473a2cbd2 Mon Sep 17 00:00:00 2001 From: Marius Meisenzahl Date: Thu, 24 Dec 2020 10:23:57 +0100 Subject: [PATCH 18/96] Save releases as property of device --- src/Interfaces/FwupdManager.vala | 5 +++-- src/Objects/Device.vala | 2 ++ src/Views/FirmwareDevicePage.vala | 16 +++++----------- src/Views/FirmwareDevicesView.vala | 6 +++--- src/Views/FirmwareReleasesView.vala | 5 ++--- 5 files changed, 15 insertions(+), 19 deletions(-) diff --git a/src/Interfaces/FwupdManager.vala b/src/Interfaces/FwupdManager.vala index 3a15fe984..83449d78f 100644 --- a/src/Interfaces/FwupdManager.vala +++ b/src/Interfaces/FwupdManager.vala @@ -58,6 +58,7 @@ public class About.FwupdManager : Object { switch (key) { case "DeviceId": device.id = _device.lookup (key).get_string (); + device.releases = get_releases (device.id); break; case "Name": device.name = _device.lookup (key).get_string (); @@ -78,7 +79,7 @@ public class About.FwupdManager : Object { break; case "Icon": var icons = _device.lookup (key).get_strv (); - device.icon = icons.length > 0 ? icons[0] : "unknown"; + device.icon = icons.length > 0 ? icons[0] : "application-x-firmware"; break; case "Guid": device.guids = _device.lookup (key).get_strv (); @@ -102,7 +103,7 @@ public class About.FwupdManager : Object { return devices_list; } - public List get_releases (string id) { + private List get_releases (string id) { var releases_list = new List (); try { diff --git a/src/Objects/Device.vala b/src/Objects/Device.vala index 20e43a928..a6c1fedf9 100644 --- a/src/Objects/Device.vala +++ b/src/Objects/Device.vala @@ -29,4 +29,6 @@ public class About.Device : Object { public string[] guids { get; set; } public uint64 flags { get; set; } public uint32 install_duration { get; set; } + + public List releases { get; owned set; } } diff --git a/src/Views/FirmwareDevicePage.vala b/src/Views/FirmwareDevicePage.vala index 84dc49d06..bf92f11d7 100644 --- a/src/Views/FirmwareDevicePage.vala +++ b/src/Views/FirmwareDevicePage.vala @@ -26,11 +26,10 @@ public class About.FirmwareDevicePage : Granite.SimpleSettingsPage { private Gtk.Grid flags_grid; private Gtk.Button verify_button; private Gtk.Button show_releases_button; - private Gtk.Label install_duration_label; private Gtk.Label install_duration_value_label; public signal void verify (string device_id); - public signal void show_releases (string device_id); + public signal void show_releases (Device device); public FirmwareDevicePage (Device device) { Object ( @@ -73,23 +72,18 @@ public class About.FirmwareDevicePage : Granite.SimpleSettingsPage { } } - verify_button.sensitive = device.install_duration > 0; - show_releases_button.sensitive = device.install_duration > 0; - install_duration_label.visible = device.install_duration > 0; - install_duration_value_label.visible = device.install_duration > 0; - if (device.install_duration > 0) { install_duration_value_label.label = "%lu s".printf (device.install_duration); - } else { - install_duration_value_label.label = ""; } + verify_button.sensitive = device.releases.length() > 0; verify_button.clicked.connect (() => { verify (device.id); }); + show_releases_button.sensitive = device.releases.length() > 0; show_releases_button.clicked.connect (() => { - show_releases (device.id); + show_releases (device); }); } @@ -131,7 +125,7 @@ public class About.FirmwareDevicePage : Granite.SimpleSettingsPage { row_spacing = 4 }; - install_duration_label = new Gtk.Label (_("Install Duration:")) { + var install_duration_label = new Gtk.Label (_("Install Duration:")) { xalign = 1 }; diff --git a/src/Views/FirmwareDevicesView.vala b/src/Views/FirmwareDevicesView.vala index bd4f45c6a..891ccd02d 100644 --- a/src/Views/FirmwareDevicesView.vala +++ b/src/Views/FirmwareDevicesView.vala @@ -21,7 +21,7 @@ public class About.FirmwareDevicesView : Gtk.Paned { public signal void verify (string device_id); - public signal void show_releases (string device_id); + public signal void show_releases (Device device); construct { var stack = new Gtk.Stack (); @@ -32,8 +32,8 @@ public class About.FirmwareDevicesView : Gtk.Paned { page.verify.connect ((device_id) => { verify (device_id); }); - page.show_releases.connect ((device_id) => { - show_releases (device_id); + page.show_releases.connect ((device) => { + show_releases (device); }); stack.add_named (page, device.id); diff --git a/src/Views/FirmwareReleasesView.vala b/src/Views/FirmwareReleasesView.vala index e91671ed2..bcb5bc195 100644 --- a/src/Views/FirmwareReleasesView.vala +++ b/src/Views/FirmwareReleasesView.vala @@ -31,13 +31,12 @@ public class About.FirmwareReleasesView : Gtk.Paned { add (stack); } - public void get_releases (string device_id) { + public void get_releases (Device device) { foreach (Gtk.Widget element in stack.get_children ()) { stack.remove (element); } - var fwupd_manager = FwupdManager.get_instance (); - foreach (var release in fwupd_manager.get_releases (device_id)) { + foreach (var release in device.releases) { var page = new FirmwareReleasePage (release); stack.add_named (page, release.id); From e7f02980f186e57810b37d94fc08326019d3402e Mon Sep 17 00:00:00 2001 From: Marius Meisenzahl Date: Thu, 24 Dec 2020 10:32:08 +0100 Subject: [PATCH 19/96] Add update error --- src/Interfaces/FwupdManager.vala | 3 +++ src/Objects/Device.vala | 1 + src/Views/FirmwareDevicePage.vala | 21 ++++++++++++++++++--- 3 files changed, 22 insertions(+), 3 deletions(-) diff --git a/src/Interfaces/FwupdManager.vala b/src/Interfaces/FwupdManager.vala index 83449d78f..dc6808cc6 100644 --- a/src/Interfaces/FwupdManager.vala +++ b/src/Interfaces/FwupdManager.vala @@ -90,6 +90,9 @@ public class About.FwupdManager : Object { case "InstallDuration": device.install_duration = _device.lookup (key).get_uint32 (); break; + case "UpdateError": + device.update_error = _device.lookup (key).get_string (); + break; default: break; } diff --git a/src/Objects/Device.vala b/src/Objects/Device.vala index a6c1fedf9..54cb82130 100644 --- a/src/Objects/Device.vala +++ b/src/Objects/Device.vala @@ -29,6 +29,7 @@ public class About.Device : Object { public string[] guids { get; set; } public uint64 flags { get; set; } public uint32 install_duration { get; set; } + public string update_error { get; set; } public List releases { get; owned set; } } diff --git a/src/Views/FirmwareDevicePage.vala b/src/Views/FirmwareDevicePage.vala index bf92f11d7..a1edab2b2 100644 --- a/src/Views/FirmwareDevicePage.vala +++ b/src/Views/FirmwareDevicePage.vala @@ -24,9 +24,11 @@ public class About.FirmwareDevicePage : Granite.SimpleSettingsPage { private Gtk.Label vendor_value_label; private Gtk.Grid guids_grid; private Gtk.Grid flags_grid; + private Gtk.Label update_error_value_label; + private Gtk.Label install_duration_value_label; + private Gtk.Button verify_button; private Gtk.Button show_releases_button; - private Gtk.Label install_duration_value_label; public signal void verify (string device_id); public signal void show_releases (Device device); @@ -72,6 +74,8 @@ public class About.FirmwareDevicePage : Granite.SimpleSettingsPage { } } + update_error_value_label.label = device.update_error; + if (device.install_duration > 0) { install_duration_value_label.label = "%lu s".printf (device.install_duration); } @@ -125,6 +129,15 @@ public class About.FirmwareDevicePage : Granite.SimpleSettingsPage { row_spacing = 4 }; + var update_error_label = new Gtk.Label (_("Update Error:")) { + xalign = 1 + }; + + update_error_value_label = new Gtk.Label ("") { + xalign = 0, + hexpand = true + }; + var install_duration_label = new Gtk.Label (_("Install Duration:")) { xalign = 1 }; @@ -142,8 +155,10 @@ public class About.FirmwareDevicePage : Granite.SimpleSettingsPage { content_area.attach (guids_grid, 1, 3, 1, 1); content_area.attach (flags_label, 0, 4, 1, 1); content_area.attach (flags_grid, 1, 4, 1, 1); - content_area.attach (install_duration_label, 0, 5, 1, 1); - content_area.attach (install_duration_value_label, 1, 5, 1, 1); + content_area.attach (update_error_label, 0, 5, 1, 1); + content_area.attach (update_error_value_label, 1, 5, 1, 1); + content_area.attach (install_duration_label, 0, 6, 1, 1); + content_area.attach (install_duration_value_label, 1, 6, 1, 1); verify_button = new Gtk.Button.with_label (_("Verify")); show_releases_button = new Gtk.Button.with_label (_("Show Releases")); From 7cc1de1108c3c2fe3f03f622d8ccd02958b4251e Mon Sep 17 00:00:00 2001 From: Marius Meisenzahl Date: Thu, 24 Dec 2020 10:37:51 +0100 Subject: [PATCH 20/96] Satisfy linter --- src/Interfaces/FwupdManager.vala | 4 +- src/Objects/DeviceFlag.vala | 92 +++++++++++++++---------------- src/Views/FirmwareDevicePage.vala | 4 +- 3 files changed, 50 insertions(+), 50 deletions(-) diff --git a/src/Interfaces/FwupdManager.vala b/src/Interfaces/FwupdManager.vala index dc6808cc6..020c5a291 100644 --- a/src/Interfaces/FwupdManager.vala +++ b/src/Interfaces/FwupdManager.vala @@ -108,7 +108,7 @@ public class About.FwupdManager : Object { private List get_releases (string id) { var releases_list = new List (); - + try { foreach (var _release in interface.get_releases (id)) { var release = new Release (); @@ -133,7 +133,7 @@ public class About.FwupdManager : Object { } catch (Error e) { warning ("Could not connect to fwupd interface: %s", e.message); } - + return releases_list; } diff --git a/src/Objects/DeviceFlag.vala b/src/Objects/DeviceFlag.vala index fcb459d4c..6bacee6e4 100644 --- a/src/Objects/DeviceFlag.vala +++ b/src/Objects/DeviceFlag.vala @@ -21,50 +21,50 @@ // https://github.com/fwupd/fwupd/blob/72df1147933de747312aa7c9892f07e7916b8a39/libfwupd/fwupd-enums.h#L133 public enum About.DeviceFlag { - NONE = (0u), /* Since: 0.1.3 */ - INTERNAL = (1u << 0), /* Since: 0.1.3 */ - UPDATABLE = (1u << 1), /* Since: 0.9.7 */ - ONLY_OFFLINE = (1u << 2), /* Since: 0.9.7 */ - REQUIRE_AC = (1u << 3), /* Since: 0.6.3 */ - LOCKED = (1u << 4), /* Since: 0.6.3 */ - SUPPORTED = (1u << 5), /* Since: 0.7.1 */ - NEEDS_BOOTLOADER = (1u << 6), /* Since: 0.7.3 */ - REGISTERED = (1u << 7), /* Since: 0.9.7 */ - NEEDS_REBOOT = (1u << 8), /* Since: 0.9.7 */ - REPORTED = (1u << 9), /* Since: 1.0.4 */ - NOTIFIED = (1u << 10), /* Since: 1.0.5 */ - USE_RUNTIME_VERSION = (1u << 11), /* Since: 1.0.6 */ - INSTALL_PARENT_FIRST = (1u << 12), /* Since: 1.0.8 */ - IS_BOOTLOADER = (1u << 13), /* Since: 1.0.8 */ - WAIT_FOR_REPLUG = (1u << 14), /* Since: 1.1.2 */ - IGNORE_VALIDATION = (1u << 15), /* Since: 1.1.2 */ - TRUSTED = (1u << 16), /* Since: 1.1.2 */ - NEEDS_SHUTDOWN = (1u << 17), /* Since: 1.2.4 */ - ANOTHER_WRITE_REQUIRED = (1u << 18), /* Since: 1.2.5 */ - NO_AUTO_INSTANCE_IDS = (1u << 19), /* Since: 1.2.5 */ - NEEDS_ACTIVATION = (1u << 20), /* Since: 1.2.6 */ - ENSURE_SEMVER = (1u << 21), /* Since: 1.2.9 */ - HISTORICAL = (1u << 22), /* Since: 1.3.2 */ - ONLY_SUPPORTED = (1u << 23), /* Since: 1.3.3 */ - WILL_DISAPPEAR = (1u << 24), /* Since: 1.3.3 */ - CAN_VERIFY = (1u << 25), /* Since: 1.3.3 */ - CAN_VERIFY_IMAGE = (1u << 26), /* Since: 1.3.3 */ - DUAL_IMAGE = (1u << 27), /* Since: 1.3.3 */ - SELF_RECOVERY = (1u << 28), /* Since: 1.3.3 */ - USABLE_DURING_UPDATE = (1u << 29), /* Since: 1.3.3 */ - VERSION_CHECK_REQUIRED = (1u << 30), /* Since: 1.3.7 */ - INSTALL_ALL_RELEASES = (1u << 31), /* Since: 1.3.7 */ - MD_SET_NAME = (1u << 32), /* Since: 1.4.0 */ - MD_SET_NAME_CATEGORY = (1u << 33), /* Since: 1.4.0 */ - MD_SET_VERFMT = (1u << 34), /* Since: 1.4.0 */ - ADD_COUNTERPART_GUIDS = (1u << 35), /* Since: 1.4.0 */ - NO_GUID_MATCHING = (1u << 36), /* Since: 1.4.1 */ - UPDATABLE_HIDDEN = (1u << 37), /* Since: 1.4.1 */ - SKIPS_RESTART = (1u << 38), /* Since: 1.5.0 */ - HAS_MULTIPLE_BRANCHES = (1u << 39), /* Since: 1.5.0 */ - BACKUP_BEFORE_INSTALL = (1u << 40), /* Since: 1.5.0 */ - MD_SET_ICON = (1u << 41), /* Since: 1.5.2 */ - UNKNOWN = 18446744073709551615; /* Since: 0.7.3 */ // using uint64.max --> ‘MAX’ undeclared here (not in a function) + NONE = (0u), /* Since: 0.1.3 */ + INTERNAL = (1u << 0), /* Since: 0.1.3 */ + UPDATABLE = (1u << 1), /* Since: 0.9.7 */ + ONLY_OFFLINE = (1u << 2), /* Since: 0.9.7 */ + REQUIRE_AC = (1u << 3), /* Since: 0.6.3 */ + LOCKED = (1u << 4), /* Since: 0.6.3 */ + SUPPORTED = (1u << 5), /* Since: 0.7.1 */ + NEEDS_BOOTLOADER = (1u << 6), /* Since: 0.7.3 */ + REGISTERED = (1u << 7), /* Since: 0.9.7 */ + NEEDS_REBOOT = (1u << 8), /* Since: 0.9.7 */ + REPORTED = (1u << 9), /* Since: 1.0.4 */ + NOTIFIED = (1u << 10), /* Since: 1.0.5 */ + USE_RUNTIME_VERSION = (1u << 11), /* Since: 1.0.6 */ + INSTALL_PARENT_FIRST = (1u << 12), /* Since: 1.0.8 */ + IS_BOOTLOADER= (1u << 13), /* Since: 1.0.8 */ + WAIT_FOR_REPLUG = (1u << 14), /* Since: 1.1.2 */ + IGNORE_VALIDATION = (1u << 15), /* Since: 1.1.2 */ + TRUSTED = (1u << 16), /* Since: 1.1.2 */ + NEEDS_SHUTDOWN = (1u << 17), /* Since: 1.2.4 */ + ANOTHER_WRITE_REQUIRED = (1u << 18), /* Since: 1.2.5 */ + NO_AUTO_INSTANCE_IDS = (1u << 19), /* Since: 1.2.5 */ + NEEDS_ACTIVATION = (1u << 20), /* Since: 1.2.6 */ + ENSURE_SEMVER= (1u << 21), /* Since: 1.2.9 */ + HISTORICAL = (1u << 22), /* Since: 1.3.2 */ + ONLY_SUPPORTED = (1u << 23), /* Since: 1.3.3 */ + WILL_DISAPPEAR = (1u << 24), /* Since: 1.3.3 */ + CAN_VERIFY = (1u << 25), /* Since: 1.3.3 */ + CAN_VERIFY_IMAGE = (1u << 26), /* Since: 1.3.3 */ + DUAL_IMAGE = (1u << 27), /* Since: 1.3.3 */ + SELF_RECOVERY= (1u << 28), /* Since: 1.3.3 */ + USABLE_DURING_UPDATE = (1u << 29), /* Since: 1.3.3 */ + VERSION_CHECK_REQUIRED = (1u << 30), /* Since: 1.3.7 */ + INSTALL_ALL_RELEASES = (1u << 31), /* Since: 1.3.7 */ + MD_SET_NAME= (1u << 32), /* Since: 1.4.0 */ + MD_SET_NAME_CATEGORY = (1u << 33), /* Since: 1.4.0 */ + MD_SET_VERFMT= (1u << 34), /* Since: 1.4.0 */ + ADD_COUNTERPART_GUIDS= (1u << 35), /* Since: 1.4.0 */ + NO_GUID_MATCHING = (1u << 36), /* Since: 1.4.1 */ + UPDATABLE_HIDDEN = (1u << 37), /* Since: 1.4.1 */ + SKIPS_RESTART= (1u << 38), /* Since: 1.5.0 */ + HAS_MULTIPLE_BRANCHES = (1u << 39), /* Since: 1.5.0 */ + BACKUP_BEFORE_INSTALL = (1u << 40), /* Since: 1.5.0 */ + MD_SET_ICON = (1u << 41), /* Since: 1.5.2 */ + UNKNOWN = 18446744073709551615; /* Since: 0.7.3 */ // using uint64.max --> ‘MAX’ undeclared here (not in a function) public static List get_list (uint64 flags) { var list = new List (); @@ -206,7 +206,7 @@ public enum About.DeviceFlag { } // https://gitlab.gnome.org/hughsie/gnome-firmware-updater/-/blob/f5281078e3cfade7ff919c812ba63de22431aaf2/src/gfu-common.c#L249 - public string? to_string() { + public string? to_string () { switch (this) { case NONE: return null; @@ -297,7 +297,7 @@ public enum About.DeviceFlag { case UNKNOWN: return null; default: - return null; + return null; } } diff --git a/src/Views/FirmwareDevicePage.vala b/src/Views/FirmwareDevicePage.vala index a1edab2b2..aaac56cfb 100644 --- a/src/Views/FirmwareDevicePage.vala +++ b/src/Views/FirmwareDevicePage.vala @@ -80,12 +80,12 @@ public class About.FirmwareDevicePage : Granite.SimpleSettingsPage { install_duration_value_label.label = "%lu s".printf (device.install_duration); } - verify_button.sensitive = device.releases.length() > 0; + verify_button.sensitive = device.releases.length () > 0; verify_button.clicked.connect (() => { verify (device.id); }); - show_releases_button.sensitive = device.releases.length() > 0; + show_releases_button.sensitive = device.releases.length () > 0; show_releases_button.clicked.connect (() => { show_releases (device); }); From 3f2bfa8c8880f74a0a2d66d88365e07f34bdcf85 Mon Sep 17 00:00:00 2001 From: Marius Meisenzahl Date: Thu, 24 Dec 2020 12:11:06 +0100 Subject: [PATCH 21/96] Show release information --- src/Interfaces/FwupdManager.vala | 69 +++++++--- src/Objects/Release.vala | 13 +- src/Views/FirmwareDevicePage.vala | 2 + src/Views/FirmwareReleasePage.vala | 190 +++++++++++++++++++++++++++- src/Views/FirmwareReleasesView.vala | 25 ++-- src/Views/FirmwareView.vala | 4 +- 6 files changed, 267 insertions(+), 36 deletions(-) diff --git a/src/Interfaces/FwupdManager.vala b/src/Interfaces/FwupdManager.vala index 020c5a291..8346317d4 100644 --- a/src/Interfaces/FwupdManager.vala +++ b/src/Interfaces/FwupdManager.vala @@ -52,46 +52,46 @@ public class About.FwupdManager : Object { var devices_list = new List (); try { - foreach (var _device in interface.get_devices ()) { + foreach (var v in interface.get_devices ()) { var device = new Device (); - foreach (var key in _device.get_keys ()) { + foreach (var key in v.get_keys ()) { switch (key) { case "DeviceId": - device.id = _device.lookup (key).get_string (); + device.id = v.lookup (key).get_string (); device.releases = get_releases (device.id); break; case "Name": - device.name = _device.lookup (key).get_string (); + device.name = v.lookup (key).get_string (); break; case "Summary": - device.summary = _device.lookup (key).get_string (); + device.summary = v.lookup (key).get_string (); break; case "Vendor": - device.vendor = _device.lookup (key).get_string (); + device.vendor = v.lookup (key).get_string (); break; case "VendorId": if (device.vendor == null) { - device.vendor = _device.lookup (key).get_string (); + device.vendor = v.lookup (key).get_string (); } break; case "Version": - device.version = _device.lookup (key).get_string (); + device.version = v.lookup (key).get_string (); break; case "Icon": - var icons = _device.lookup (key).get_strv (); + var icons = v.lookup (key).get_strv (); device.icon = icons.length > 0 ? icons[0] : "application-x-firmware"; break; case "Guid": - device.guids = _device.lookup (key).get_strv (); + device.guids = v.lookup (key).get_strv (); break; case "Flags": - device.flags = _device.lookup (key).get_uint64 (); + device.flags = v.lookup (key).get_uint64 (); break; case "InstallDuration": - device.install_duration = _device.lookup (key).get_uint32 (); + device.install_duration = v.lookup (key).get_uint32 (); break; case "UpdateError": - device.update_error = _device.lookup (key).get_string (); + device.update_error = v.lookup (key).get_string (); break; default: break; @@ -110,19 +110,52 @@ public class About.FwupdManager : Object { var releases_list = new List (); try { - foreach (var _release in interface.get_releases (id)) { + foreach (var v in interface.get_releases (id)) { var release = new Release (); release.icon = "security-high"; - foreach (var key in _release.get_keys ()) { + foreach (var key in v.get_keys ()) { switch (key) { case "Filename": - release.id = _release.lookup (key).get_string (); + release.filename = v.lookup (key).get_string (); break; case "Name": - release.name = _release.lookup (key).get_string (); + release.name = v.lookup (key).get_string (); break; case "Summary": - release.summary = _release.lookup (key).get_string (); + release.summary = v.lookup (key).get_string (); + break; + case "Version": + release.version = v.lookup (key).get_string (); + break; + case "Description": + release.description = v.lookup (key).get_string (); + break; + case "Protocol": + release.protocol = v.lookup (key).get_string (); + break; + case "RemoteId": + release.remote_id = v.lookup (key).get_string (); + break; + case "AppstreamId": + release.appstream_id = v.lookup (key).get_string (); + break; + case "Checksum": + release.checksum = v.lookup (key).get_string (); + break; + case "Vendor": + release.vendor = v.lookup (key).get_string (); + break; + case "Size": + release.size = v.lookup (key).get_uint64 (); + break; + case "License": + release.license = v.lookup (key).get_string (); + break; + case "TrustFlags": + release.flags = v.lookup (key).get_uint64 (); + break; + case "InstallDuration": + release.install_duration = v.lookup (key).get_uint32 (); break; default: break; diff --git a/src/Objects/Release.vala b/src/Objects/Release.vala index 82f526cee..fef011221 100644 --- a/src/Objects/Release.vala +++ b/src/Objects/Release.vala @@ -20,8 +20,19 @@ */ public class About.Release : Object { - public string id { get; set; } + public string filename { get; set; } public string name { get; set; } public string summary { get; set; } public string icon { get; set; } + public string version { get; set; } + public string description { get; set; } + public string protocol { get; set; } + public string remote_id { get; set; } + public string appstream_id { get; set; } + public string checksum { get; set; } + public string vendor { get; set; } + public uint64 size { get; set; } + public string license { get; set; } + public uint64 flags { get; set; } + public uint32 install_duration { get; set; } } diff --git a/src/Views/FirmwareDevicePage.vala b/src/Views/FirmwareDevicePage.vala index aaac56cfb..10b0a8fe6 100644 --- a/src/Views/FirmwareDevicePage.vala +++ b/src/Views/FirmwareDevicePage.vala @@ -41,7 +41,9 @@ public class About.FirmwareDevicePage : Granite.SimpleSettingsPage { ); version_value_label.label = device.version; + vendor_value_label.label = device.vendor; + foreach (var guid in device.guids) { var label = new Gtk.Label (guid) { xalign = 0, diff --git a/src/Views/FirmwareReleasePage.vala b/src/Views/FirmwareReleasePage.vala index 9de0d61a3..5d47d75ed 100644 --- a/src/Views/FirmwareReleasePage.vala +++ b/src/Views/FirmwareReleasePage.vala @@ -20,13 +20,201 @@ */ public class About.FirmwareReleasePage : Granite.SimpleSettingsPage { + private Gtk.Label version_value_label; + private Gtk.Label summary_value_label; + private Gtk.Label description_value_label; + private Gtk.Label filename_value_label; + private Gtk.Label protocol_value_label; + private Gtk.Label remote_id_value_label; + private Gtk.Label appstream_id_value_label; + private Gtk.Label checksum_value_label; + private Gtk.Label vendor_value_label; + private Gtk.Label size_value_label; + private Gtk.Label license_value_label; + private Gtk.Label flags_value_label; + private Gtk.Label install_duration_value_label; + public FirmwareReleasePage (Release release) { Object ( icon_name: release.icon, status: release.summary, title: release.name ); + + version_value_label.label = release.version; + + summary_value_label.label = release.summary; + + description_value_label.label = release.description; + + filename_value_label.label = release.filename; + + protocol_value_label.label = release.protocol; + + remote_id_value_label.label = release.remote_id; + + appstream_id_value_label.label = release.appstream_id; + + checksum_value_label.label = release.checksum; + + vendor_value_label.label = release.vendor; + + size_value_label.label = "%.1f kB".printf ((release.size / 1000.0)); + + license_value_label.label = release.license; + + flags_value_label.label = "%llu".printf (release.flags); + + if (release.install_duration > 0) { + install_duration_value_label.label = "%lu s".printf (release.install_duration); + } } - construct {} + construct { + var version_label = new Gtk.Label (_("Version:")) { + xalign = 1 + }; + + version_value_label = new Gtk.Label ("") { + xalign = 0, + hexpand = true + }; + + var summary_label = new Gtk.Label (_("Summary:")) { + xalign = 1 + }; + + summary_value_label = new Gtk.Label ("") { + xalign = 0, + hexpand = true + }; + + var description_label = new Gtk.Label (_("Description:")) { + xalign = 1, + yalign = 0 + }; + + description_value_label = new Gtk.Label ("") { + xalign = 0, + hexpand = true, + wrap = true + }; + + var filename_label = new Gtk.Label (_("Filename:")) { + xalign = 1 + }; + + filename_value_label = new Gtk.Label ("") { + xalign = 0, + hexpand = true + }; + + var protocol_label = new Gtk.Label (_("Protocol:")) { + xalign = 1 + }; + + protocol_value_label = new Gtk.Label ("") { + xalign = 0, + hexpand = true + }; + + var remote_id_label = new Gtk.Label (_("Remote ID:")) { + xalign = 1 + }; + + remote_id_value_label = new Gtk.Label ("") { + xalign = 0, + hexpand = true + }; + + var appstream_id_label = new Gtk.Label (_("Appstream ID:")) { + xalign = 1 + }; + + appstream_id_value_label = new Gtk.Label ("") { + xalign = 0, + hexpand = true + }; + + var checksum_label = new Gtk.Label (_("Checksum:")) { + xalign = 1 + }; + + checksum_value_label = new Gtk.Label ("") { + xalign = 0, + hexpand = true + }; + + var vendor_label = new Gtk.Label (_("Vendor:")) { + xalign = 1 + }; + + vendor_value_label = new Gtk.Label ("") { + xalign = 0, + hexpand = true + }; + + var size_label = new Gtk.Label (_("Size:")) { + xalign = 1 + }; + + size_value_label = new Gtk.Label ("") { + xalign = 0, + hexpand = true + }; + + var license_label = new Gtk.Label (_("License:")) { + xalign = 1 + }; + + license_value_label = new Gtk.Label ("") { + xalign = 0, + hexpand = true + }; + + var flags_label = new Gtk.Label (_("Flags:")) { + xalign = 1 + }; + + flags_value_label = new Gtk.Label ("") { + xalign = 0, + hexpand = true + }; + + var install_duration_label = new Gtk.Label (_("Install Duration:")) { + xalign = 1 + }; + + install_duration_value_label = new Gtk.Label ("") { + xalign = 0, + hexpand = true + }; + + content_area.attach (version_label, 0, 1, 1, 1); + content_area.attach (version_value_label, 1, 1, 1, 1); + content_area.attach (summary_label, 0, 2, 1, 1); + content_area.attach (summary_value_label, 1, 2, 1, 1); + content_area.attach (description_label, 0, 3, 1, 1); + content_area.attach (description_value_label, 1, 3, 1, 1); + content_area.attach (filename_label, 0, 4, 1, 1); + content_area.attach (filename_value_label, 1, 4, 1, 1); + content_area.attach (protocol_label, 0, 5, 1, 1); + content_area.attach (protocol_value_label, 1, 5, 1, 1); + content_area.attach (remote_id_label, 0, 6, 1, 1); + content_area.attach (remote_id_value_label, 1, 6, 1, 1); + content_area.attach (appstream_id_label, 0, 7, 1, 1); + content_area.attach (appstream_id_value_label, 1, 7, 1, 1); + content_area.attach (checksum_label, 0, 8, 1, 1); + content_area.attach (checksum_value_label, 1, 8, 1, 1); + content_area.attach (vendor_label, 0, 9, 1, 1); + content_area.attach (vendor_value_label, 1, 9, 1, 1); + content_area.attach (size_label, 0, 10, 1, 1); + content_area.attach (size_value_label, 1, 10, 1, 1); + content_area.attach (license_label, 0, 11, 1, 1); + content_area.attach (license_value_label, 1, 11, 1, 1); + content_area.attach (flags_label, 0, 12, 1, 1); + content_area.attach (flags_value_label, 1, 12, 1, 1); + content_area.attach (install_duration_label, 0, 13, 1, 1); + content_area.attach (install_duration_value_label, 1, 13, 1, 1); + } } diff --git a/src/Views/FirmwareReleasesView.vala b/src/Views/FirmwareReleasesView.vala index bcb5bc195..b25640960 100644 --- a/src/Views/FirmwareReleasesView.vala +++ b/src/Views/FirmwareReleasesView.vala @@ -20,26 +20,23 @@ */ public class About.FirmwareReleasesView : Gtk.Paned { - private Gtk.Stack stack; - - construct { - stack = new Gtk.Stack (); - - var settings_sidebar = new Granite.SettingsSidebar (stack); - - add (settings_sidebar); - add (stack); - } - public void get_releases (Device device) { - foreach (Gtk.Widget element in stack.get_children ()) { - stack.remove (element); + foreach (Gtk.Widget element in get_children ()) { + remove (element); } + var stack = new Gtk.Stack (); + foreach (var release in device.releases) { var page = new FirmwareReleasePage (release); - stack.add_named (page, release.id); + stack.add_named (page, release.filename); } + + var settings_sidebar = new Granite.SettingsSidebar (stack); + + add (settings_sidebar); + add (stack); + show_all (); } } diff --git a/src/Views/FirmwareView.vala b/src/Views/FirmwareView.vala index 011731880..1ff3a9c3c 100644 --- a/src/Views/FirmwareView.vala +++ b/src/Views/FirmwareView.vala @@ -24,8 +24,8 @@ public class About.FirmwareView : Gtk.Stack { var firmware_devices_view = new FirmwareDevicesView (); var firmware_releases_view = new FirmwareReleasesView (); - firmware_devices_view.show_releases.connect ((device_id) => { - firmware_releases_view.get_releases (device_id); + firmware_devices_view.show_releases.connect ((device) => { + firmware_releases_view.get_releases (device); set_visible_child_name ("releases"); }); From 14cfd829c003aea29cb0b029eb4d06244ff3a141 Mon Sep 17 00:00:00 2001 From: Marius Meisenzahl Date: Thu, 24 Dec 2020 13:05:10 +0100 Subject: [PATCH 22/96] Pretty print file size and time --- src/Utils/Formatter.vala | 57 ++++++++++++++++++++++++++++++ src/Views/FirmwareDevicePage.vala | 4 +-- src/Views/FirmwareReleasePage.vala | 6 ++-- src/meson.build | 1 + 4 files changed, 61 insertions(+), 7 deletions(-) create mode 100644 src/Utils/Formatter.vala diff --git a/src/Utils/Formatter.vala b/src/Utils/Formatter.vala new file mode 100644 index 000000000..8c8473a54 --- /dev/null +++ b/src/Utils/Formatter.vala @@ -0,0 +1,57 @@ +/* +* Copyright (c) 2020 elementary, Inc. (https://elementary.io) +* +* 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 3 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 +* +* Authored by: Marius Meisenzahl +*/ + +public class About.Formatter : Granite.SimpleSettingsPage { + public static string bytes_to_string (uint64 bytes) { + if (bytes > 1000000000) { + return "%.1f GB".printf (bytes / 1000000000.0); + } else if (bytes > 1000000) { + return "%.1f MB".printf (bytes / 1000000.0); + } else if (bytes > 1000) { + return "%.1f kB".printf (bytes / 1000.0); + } + + return "%llu B".printf (bytes); + } + + public static string? seconds_to_string (uint64 seconds) { + uint64 minutes, hours; + + if (seconds == 0) { + return null; + } + + if (seconds >= 60) { + minutes = seconds / 60; + seconds = seconds % 60; + + if (minutes >= 60) { + hours = minutes / 60; + minutes = minutes % 60; + return _("%llu hr, %llu min, %llu sec").printf (hours, minutes, seconds); + } + + return _("%llu min, %llu sec").printf (minutes, seconds); + } + + return _("%llu sec").printf (seconds); + } +} diff --git a/src/Views/FirmwareDevicePage.vala b/src/Views/FirmwareDevicePage.vala index 10b0a8fe6..a1ad0d379 100644 --- a/src/Views/FirmwareDevicePage.vala +++ b/src/Views/FirmwareDevicePage.vala @@ -78,9 +78,7 @@ public class About.FirmwareDevicePage : Granite.SimpleSettingsPage { update_error_value_label.label = device.update_error; - if (device.install_duration > 0) { - install_duration_value_label.label = "%lu s".printf (device.install_duration); - } + install_duration_value_label.label = Formatter.seconds_to_string (device.install_duration); verify_button.sensitive = device.releases.length () > 0; verify_button.clicked.connect (() => { diff --git a/src/Views/FirmwareReleasePage.vala b/src/Views/FirmwareReleasePage.vala index 5d47d75ed..3986ef7b5 100644 --- a/src/Views/FirmwareReleasePage.vala +++ b/src/Views/FirmwareReleasePage.vala @@ -59,15 +59,13 @@ public class About.FirmwareReleasePage : Granite.SimpleSettingsPage { vendor_value_label.label = release.vendor; - size_value_label.label = "%.1f kB".printf ((release.size / 1000.0)); + size_value_label.label = Formatter.bytes_to_string (release.size); license_value_label.label = release.license; flags_value_label.label = "%llu".printf (release.flags); - if (release.install_duration > 0) { - install_duration_value_label.label = "%lu s".printf (release.install_duration); - } + install_duration_value_label.label = Formatter.seconds_to_string (release.install_duration); } construct { diff --git a/src/meson.build b/src/meson.build index bcb133ac0..3f9c7392e 100644 --- a/src/meson.build +++ b/src/meson.build @@ -5,6 +5,7 @@ plug_files = files( 'Objects/Release.vala', 'Interfaces/FwupdManager.vala', 'Utils/ARMPartDecoder.vala', + 'Utils/Formatter.vala', 'Views/FirmwareDevicePage.vala', 'Views/FirmwareDevicesView.vala', 'Views/FirmwareReleasePage.vala', From 9e07a09d2e0f3d5e82b3e2f2c90bd9ebc70bb912 Mon Sep 17 00:00:00 2001 From: Marius Meisenzahl Date: Fri, 25 Dec 2020 11:44:09 +0100 Subject: [PATCH 23/96] Add dialog to install release --- src/Interfaces/FwupdManager.vala | 2 +- src/Objects/Release.vala | 2 +- src/Objects/ReleaseFlag.vala | 62 ++++++++++++++++++++++++++++++ src/Views/FirmwareReleasePage.vala | 54 ++++++++++++++++++-------- src/meson.build | 1 + 5 files changed, 103 insertions(+), 18 deletions(-) create mode 100644 src/Objects/ReleaseFlag.vala diff --git a/src/Interfaces/FwupdManager.vala b/src/Interfaces/FwupdManager.vala index 8346317d4..f6a71f491 100644 --- a/src/Interfaces/FwupdManager.vala +++ b/src/Interfaces/FwupdManager.vala @@ -152,7 +152,7 @@ public class About.FwupdManager : Object { release.license = v.lookup (key).get_string (); break; case "TrustFlags": - release.flags = v.lookup (key).get_uint64 (); + release.flag = ReleaseFlag.from_uint64 (v.lookup (key).get_uint64 ()); break; case "InstallDuration": release.install_duration = v.lookup (key).get_uint32 (); diff --git a/src/Objects/Release.vala b/src/Objects/Release.vala index fef011221..897d1ee02 100644 --- a/src/Objects/Release.vala +++ b/src/Objects/Release.vala @@ -33,6 +33,6 @@ public class About.Release : Object { public string vendor { get; set; } public uint64 size { get; set; } public string license { get; set; } - public uint64 flags { get; set; } + public ReleaseFlag flag { get; set; } public uint32 install_duration { get; set; } } diff --git a/src/Objects/ReleaseFlag.vala b/src/Objects/ReleaseFlag.vala new file mode 100644 index 000000000..0746279d6 --- /dev/null +++ b/src/Objects/ReleaseFlag.vala @@ -0,0 +1,62 @@ +/* +* Copyright (c) 2020 elementary, Inc. (https://elementary.io) +* +* 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 3 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 +* +* Authored by: Marius Meisenzahl +*/ + +// https://github.com/fwupd/fwupd/blob/72df1147933de747312aa7c9892f07e7916b8a39/libfwupd/fwupd-enums.h#L192 +public enum About.ReleaseFlag { + NONE = (0u), /* Since: 1.2.6 */ + TRUSTED_PAYLOAD = (1u << 0), /* Since: 1.2.6 */ + TRUSTED_METADATA = (1u << 1), /* Since: 1.2.6 */ + IS_UPGRADE = (1u << 2), /* Since: 1.2.6 */ + IS_DOWNGRADE = (1u << 3), /* Since: 1.2.6 */ + BLOCKED_VERSION = (1u << 4), /* Since: 1.2.6 */ + BLOCKED_APPROVAL = (1u << 5), /* Since: 1.2.6 */ + IS_ALTERNATE_BRANCH = (1u << 6), /* Since: 1.5.0 */ + UNKNOWN = 18446744073709551615; /* Since: 1.2.6 */ // using uint64.max --> ‘MAX’ undeclared here (not in a function) + + public static ReleaseFlag from_uint64 (uint64 flag) { + if ((flag & (0u)) > 0) { + return ReleaseFlag.NONE; + } + else if ((flag & (1u << 0)) > 0) { + return ReleaseFlag.TRUSTED_PAYLOAD; + } + else if ((flag & (1u << 1)) > 0) { + return ReleaseFlag.TRUSTED_METADATA; + } + else if ((flag & (1u << 2)) > 0) { + return ReleaseFlag.IS_UPGRADE; + } + else if ((flag & (1u << 3)) > 0) { + return ReleaseFlag.IS_DOWNGRADE; + } + else if ((flag & (1u << 4)) > 0) { + return ReleaseFlag.BLOCKED_VERSION; + } + else if ((flag & (1u << 5)) > 0) { + return ReleaseFlag.BLOCKED_APPROVAL; + } + else if ((flag & (1u << 6)) > 0) { + return ReleaseFlag.IS_ALTERNATE_BRANCH; + } + + return ReleaseFlag.UNKNOWN; + } +} diff --git a/src/Views/FirmwareReleasePage.vala b/src/Views/FirmwareReleasePage.vala index 3986ef7b5..507aeba72 100644 --- a/src/Views/FirmwareReleasePage.vala +++ b/src/Views/FirmwareReleasePage.vala @@ -31,7 +31,6 @@ public class About.FirmwareReleasePage : Granite.SimpleSettingsPage { private Gtk.Label vendor_value_label; private Gtk.Label size_value_label; private Gtk.Label license_value_label; - private Gtk.Label flags_value_label; private Gtk.Label install_duration_value_label; public FirmwareReleasePage (Release release) { @@ -63,9 +62,43 @@ public class About.FirmwareReleasePage : Granite.SimpleSettingsPage { license_value_label.label = release.license; - flags_value_label.label = "%llu".printf (release.flags); - install_duration_value_label.label = Formatter.seconds_to_string (release.install_duration); + + var message_dialog = new Granite.MessageDialog.with_image_from_icon_name ( + _("%s firmware version %s").printf (release.name, release.version), + _("Install this firmware file?"), + "security-high", + Gtk.ButtonsType.CANCEL + ); + + var suggested_button = new Gtk.Button.with_label (_("Install")); + suggested_button.get_style_context ().add_class (Gtk.STYLE_CLASS_SUGGESTED_ACTION); + message_dialog.add_action_widget (suggested_button, Gtk.ResponseType.ACCEPT); + + var button = new Gtk.Button (); + + switch (release.flag) { + case ReleaseFlag.IS_UPGRADE: + button.label = _("Install Upgrade"); + break; + case ReleaseFlag.IS_DOWNGRADE: + button.label = _("Install Downgrade"); + break; + default: + button.label = _("Reinstall"); + suggested_button.label = _("Reinstall"); + message_dialog.secondary_text = _("This firmware version is already installed on the device. Reinstall this firmware file?"); + break; + } + + button.clicked.connect (() => { + message_dialog.show_all (); + if (message_dialog.run () == Gtk.ResponseType.ACCEPT) {} + + message_dialog.destroy (); + }); + + action_area.add (button); } construct { @@ -170,15 +203,6 @@ public class About.FirmwareReleasePage : Granite.SimpleSettingsPage { hexpand = true }; - var flags_label = new Gtk.Label (_("Flags:")) { - xalign = 1 - }; - - flags_value_label = new Gtk.Label ("") { - xalign = 0, - hexpand = true - }; - var install_duration_label = new Gtk.Label (_("Install Duration:")) { xalign = 1 }; @@ -210,9 +234,7 @@ public class About.FirmwareReleasePage : Granite.SimpleSettingsPage { content_area.attach (size_value_label, 1, 10, 1, 1); content_area.attach (license_label, 0, 11, 1, 1); content_area.attach (license_value_label, 1, 11, 1, 1); - content_area.attach (flags_label, 0, 12, 1, 1); - content_area.attach (flags_value_label, 1, 12, 1, 1); - content_area.attach (install_duration_label, 0, 13, 1, 1); - content_area.attach (install_duration_value_label, 1, 13, 1, 1); + content_area.attach (install_duration_label, 0, 12, 1, 1); + content_area.attach (install_duration_value_label, 1, 12, 1, 1); } } diff --git a/src/meson.build b/src/meson.build index 3f9c7392e..648e96131 100644 --- a/src/meson.build +++ b/src/meson.build @@ -3,6 +3,7 @@ plug_files = files( 'Objects/Device.vala', 'Objects/DeviceFlag.vala', 'Objects/Release.vala', + 'Objects/ReleaseFlag.vala', 'Interfaces/FwupdManager.vala', 'Utils/ARMPartDecoder.vala', 'Utils/Formatter.vala', From ad144c26be114dd233b0aa50a65fee7524a5639a Mon Sep 17 00:00:00 2001 From: Marius Meisenzahl Date: Fri, 25 Dec 2020 12:03:18 +0100 Subject: [PATCH 24/96] Format release description --- src/Interfaces/FwupdManager.vala | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/Interfaces/FwupdManager.vala b/src/Interfaces/FwupdManager.vala index f6a71f491..a6b42a75a 100644 --- a/src/Interfaces/FwupdManager.vala +++ b/src/Interfaces/FwupdManager.vala @@ -128,7 +128,16 @@ public class About.FwupdManager : Object { release.version = v.lookup (key).get_string (); break; case "Description": - release.description = v.lookup (key).get_string (); + release.description = v.lookup (key).get_string () + .replace ("

", "") + .replace ("

", "\n\n") + .replace ("
  • ", " • ") + .replace ("
  • ", "\n") + .replace ("
      ", "") + .replace ("
    ", "\n") + .replace ("
      ", "") + .replace ("
    ", "\n") + .strip (); break; case "Protocol": release.protocol = v.lookup (key).get_string (); From 58e05b90a0a7bb654a3dcfcc0c78c156d53411a1 Mon Sep 17 00:00:00 2001 From: Marius Meisenzahl Date: Fri, 25 Dec 2020 12:04:34 +0100 Subject: [PATCH 25/96] Add todo --- src/Interfaces/FwupdManager.vala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Interfaces/FwupdManager.vala b/src/Interfaces/FwupdManager.vala index a6b42a75a..01f65f4b1 100644 --- a/src/Interfaces/FwupdManager.vala +++ b/src/Interfaces/FwupdManager.vala @@ -135,7 +135,7 @@ public class About.FwupdManager : Object { .replace ("", "\n") .replace ("
      ", "") .replace ("
    ", "\n") - .replace ("
      ", "") + .replace ("
        ", "") // TODO: add support for ordered lists .replace ("
      ", "\n") .strip (); break; From 673835a03a87fb43f8330b7d6be630c153a453bc Mon Sep 17 00:00:00 2001 From: Marius Meisenzahl Date: Sun, 27 Dec 2020 09:02:44 +0100 Subject: [PATCH 26/96] Add support to install upgrade or reinstall --- src/Interfaces/FwupdManager.vala | 40 +++++++++++++++++++++++++++++ src/Objects/Release.vala | 1 + src/Views/FirmwareReleasePage.vala | 8 ++++-- src/Views/FirmwareReleasesView.vala | 2 +- src/fd.c | 5 ++++ src/meson.build | 1 + 6 files changed, 54 insertions(+), 3 deletions(-) create mode 100644 src/fd.c diff --git a/src/Interfaces/FwupdManager.vala b/src/Interfaces/FwupdManager.vala index 01f65f4b1..4d64bf57c 100644 --- a/src/Interfaces/FwupdManager.vala +++ b/src/Interfaces/FwupdManager.vala @@ -19,6 +19,8 @@ * Authored by: Marius Meisenzahl */ +extern int ro_fd (string path); + [DBus (name="org.freedesktop.fwupd")] public interface About.FwupdInterface : Object { [DBus (name = "HostProduct")] @@ -32,6 +34,12 @@ public interface About.FwupdInterface : Object { [DBus (name = "Verify")] public abstract void verify (string id) throws Error; + + [DBus (name = "Install")] + public abstract void install (string id, UnixInputStream handle, HashTable options) throws Error; + + [DBus (name = "GetDetails")] + public abstract HashTable[] get_details (UnixInputStream handle) throws Error; } public class About.FwupdManager : Object { @@ -166,6 +174,9 @@ public class About.FwupdManager : Object { case "InstallDuration": release.install_duration = v.lookup (key).get_uint32 (); break; + case "Uri": + release.uri = v.lookup (key).get_string (); + break; default: break; } @@ -183,6 +194,35 @@ public class About.FwupdManager : Object { interface.verify (id); } + private string get_path (Release release) { + var parts = release.uri.split ("/"); + string file_path = parts[parts.length - 1]; + return Path.build_path (Path.DIR_SEPARATOR_S, Path.DIR_SEPARATOR_S, "tmp", file_path); + } + + private UnixInputStream get_handle (Release release) { + var fd = ro_fd (get_path (release)); + return new UnixInputStream (fd, true); + } + + public void install (string id, Release release) throws Error { + var handle = get_handle (release); + + // https://github.com/fwupd/fwupd/blob/c0d4c09a02a40167e9de57f82c0033bb92e24167/libfwupd/fwupd-client.c#L2045 + HashTable options = new HashTable (str_hash, str_equal); + options.insert ("reason", new Variant.string ("user-action")); + options.insert ("filename", new Variant.string (get_path (release))); + // options.insert ("offline", new Variant.boolean (true)); + options.insert ("allow-older", new Variant.boolean (true)); + options.insert ("allow-reinstall", new Variant.boolean (true)); + // options.insert ("allow-branch-switch", new Variant.boolean (true)); + // options.insert ("force", new Variant.boolean (true)); + // options.insert ("ignore-power", new Variant.boolean (true)); + options.insert ("no-history", new Variant.boolean (true)); + + interface.install (id, handle, options); + } + construct { try { interface = Bus.get_proxy_sync (BusType.SYSTEM, "org.freedesktop.fwupd", "/"); diff --git a/src/Objects/Release.vala b/src/Objects/Release.vala index 897d1ee02..ced8a60b2 100644 --- a/src/Objects/Release.vala +++ b/src/Objects/Release.vala @@ -35,4 +35,5 @@ public class About.Release : Object { public string license { get; set; } public ReleaseFlag flag { get; set; } public uint32 install_duration { get; set; } + public string uri { get; set; } } diff --git a/src/Views/FirmwareReleasePage.vala b/src/Views/FirmwareReleasePage.vala index 507aeba72..27a1f1555 100644 --- a/src/Views/FirmwareReleasePage.vala +++ b/src/Views/FirmwareReleasePage.vala @@ -33,7 +33,7 @@ public class About.FirmwareReleasePage : Granite.SimpleSettingsPage { private Gtk.Label license_value_label; private Gtk.Label install_duration_value_label; - public FirmwareReleasePage (Release release) { + public FirmwareReleasePage (Device device, Release release) { Object ( icon_name: release.icon, status: release.summary, @@ -82,7 +82,9 @@ public class About.FirmwareReleasePage : Granite.SimpleSettingsPage { button.label = _("Install Upgrade"); break; case ReleaseFlag.IS_DOWNGRADE: + // TODO: support downgrades (authentication is required) button.label = _("Install Downgrade"); + button.sensitive = false; break; default: button.label = _("Reinstall"); @@ -93,7 +95,9 @@ public class About.FirmwareReleasePage : Granite.SimpleSettingsPage { button.clicked.connect (() => { message_dialog.show_all (); - if (message_dialog.run () == Gtk.ResponseType.ACCEPT) {} + if (message_dialog.run () == Gtk.ResponseType.ACCEPT) { + FwupdManager.get_instance ().install (device.id, release); + } message_dialog.destroy (); }); diff --git a/src/Views/FirmwareReleasesView.vala b/src/Views/FirmwareReleasesView.vala index b25640960..d409ad2de 100644 --- a/src/Views/FirmwareReleasesView.vala +++ b/src/Views/FirmwareReleasesView.vala @@ -28,7 +28,7 @@ public class About.FirmwareReleasesView : Gtk.Paned { var stack = new Gtk.Stack (); foreach (var release in device.releases) { - var page = new FirmwareReleasePage (release); + var page = new FirmwareReleasePage (device, release); stack.add_named (page, release.filename); } diff --git a/src/fd.c b/src/fd.c new file mode 100644 index 000000000..ebbede61b --- /dev/null +++ b/src/fd.c @@ -0,0 +1,5 @@ +#include + +int ro_fd (const char *path) { + return open ("/tmp/8d83954fcf79453738dbeba9615a095bae9caed9-Logitech-Unifying-RQR12.10_B0032.cab", O_RDONLY); +} diff --git a/src/meson.build b/src/meson.build index 648e96131..178cf296b 100644 --- a/src/meson.build +++ b/src/meson.build @@ -1,4 +1,5 @@ plug_files = files( + 'fd.c', 'Plug.vala', 'Objects/Device.vala', 'Objects/DeviceFlag.vala', From b578a1c7bb39d7703450678a2b7807cfddc0d340 Mon Sep 17 00:00:00 2001 From: Marius Meisenzahl Date: Sun, 27 Dec 2020 09:04:10 +0100 Subject: [PATCH 27/96] Add support to install downgrade --- src/Views/FirmwareReleasePage.vala | 2 -- src/fd.c | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/src/Views/FirmwareReleasePage.vala b/src/Views/FirmwareReleasePage.vala index 27a1f1555..ad7e61a5e 100644 --- a/src/Views/FirmwareReleasePage.vala +++ b/src/Views/FirmwareReleasePage.vala @@ -82,9 +82,7 @@ public class About.FirmwareReleasePage : Granite.SimpleSettingsPage { button.label = _("Install Upgrade"); break; case ReleaseFlag.IS_DOWNGRADE: - // TODO: support downgrades (authentication is required) button.label = _("Install Downgrade"); - button.sensitive = false; break; default: button.label = _("Reinstall"); diff --git a/src/fd.c b/src/fd.c index ebbede61b..79aa23d48 100644 --- a/src/fd.c +++ b/src/fd.c @@ -1,5 +1,5 @@ #include int ro_fd (const char *path) { - return open ("/tmp/8d83954fcf79453738dbeba9615a095bae9caed9-Logitech-Unifying-RQR12.10_B0032.cab", O_RDONLY); + return open (path, O_RDONLY); } From 24f2d5caa744db65e26c65f0d46ef6f7272b3d3a Mon Sep 17 00:00:00 2001 From: Marius Meisenzahl Date: Sun, 27 Dec 2020 09:13:33 +0100 Subject: [PATCH 28/96] List device only if updatable --- src/Objects/Device.vala | 10 ++++++++++ src/Views/FirmwareDevicesView.vala | 18 ++++++++++-------- 2 files changed, 20 insertions(+), 8 deletions(-) diff --git a/src/Objects/Device.vala b/src/Objects/Device.vala index 54cb82130..7e327fe31 100644 --- a/src/Objects/Device.vala +++ b/src/Objects/Device.vala @@ -32,4 +32,14 @@ public class About.Device : Object { public string update_error { get; set; } public List releases { get; owned set; } + + public bool is (DeviceFlag flag) { + foreach (var f in DeviceFlag.get_list (flags)) { + if (f == flag) { + return true; + } + } + + return false; + } } diff --git a/src/Views/FirmwareDevicesView.vala b/src/Views/FirmwareDevicesView.vala index 891ccd02d..abfe05088 100644 --- a/src/Views/FirmwareDevicesView.vala +++ b/src/Views/FirmwareDevicesView.vala @@ -28,15 +28,17 @@ public class About.FirmwareDevicesView : Gtk.Paned { var fwupd_manager = FwupdManager.get_instance (); foreach (var device in fwupd_manager.get_devices ()) { - var page = new FirmwareDevicePage (device); - page.verify.connect ((device_id) => { - verify (device_id); - }); - page.show_releases.connect ((device) => { - show_releases (device); - }); + if (device.is (DeviceFlag.UPDATABLE)) { + var page = new FirmwareDevicePage (device); + page.verify.connect ((device_id) => { + verify (device_id); + }); + page.show_releases.connect ((device) => { + show_releases (device); + }); - stack.add_named (page, device.id); + stack.add_named (page, device.id); + } } var settings_sidebar = new Granite.SettingsSidebar (stack); From 0e467da5ac57191610beb9ba68111348dc8cb590 Mon Sep 17 00:00:00 2001 From: Marius Meisenzahl Date: Sun, 27 Dec 2020 11:49:53 +0100 Subject: [PATCH 29/96] Separate operating system and hardware views --- src/Plug.vala | 9 ++++++--- src/Views/HardwareView.vala | 2 ++ .../{SystemView.vala => OperatingSystemView.vala} | 10 +--------- src/meson.build | 2 +- 4 files changed, 10 insertions(+), 13 deletions(-) rename src/Views/{SystemView.vala => OperatingSystemView.vala} (96%) diff --git a/src/Plug.vala b/src/Plug.vala index 368a7ccff..476d58653 100644 --- a/src/Plug.vala +++ b/src/Plug.vala @@ -17,7 +17,7 @@ public class About.Plug : Switchboard.Plug { private Gtk.Stack stack; - private SystemView system_view; + private OperatingSystemView operating_system_view; private Gtk.Grid main_grid; public Plug () { @@ -37,8 +37,11 @@ public class About.Plug : Switchboard.Plug { stack = new Gtk.Stack (); - system_view = new SystemView (); - stack.add_titled (system_view, "system", _("System")); + operating_system_view = new OperatingSystemView (); + stack.add_titled (operating_system_view, "os", _("Operating System")); + + var hardware_view = new HardwareView (); + stack.add_titled (hardware_view, "hardware", _("Hardware")); var firmware_view = new FirmwareView (); stack.add_titled (firmware_view, "firmware", _("Firmware")); diff --git a/src/Views/HardwareView.vala b/src/Views/HardwareView.vala index 8b3fb9842..d2fe932ad 100644 --- a/src/Views/HardwareView.vala +++ b/src/Views/HardwareView.vala @@ -82,6 +82,8 @@ public class About.HardwareView : Gtk.Grid { hdd_info.ellipsize = Pango.EllipsizeMode.END; hdd_info.set_selectable (true); + halign = Gtk.Align.CENTER; + valign = Gtk.Align.CENTER; column_spacing = 6; row_spacing = 6; attach (manufacturer_logo, 0, 0, 2, 1); diff --git a/src/Views/SystemView.vala b/src/Views/OperatingSystemView.vala similarity index 96% rename from src/Views/SystemView.vala rename to src/Views/OperatingSystemView.vala index 8475efd1f..c1d982498 100644 --- a/src/Views/SystemView.vala +++ b/src/Views/OperatingSystemView.vala @@ -19,7 +19,7 @@ * Authored by: Marius Meisenzahl */ -public class About.SystemView : Gtk.Grid { +public class About.OperatingSystemView : Gtk.Grid { private string kernel_version; private string support_url; private Gtk.Label based_off; @@ -195,12 +195,6 @@ public class About.SystemView : Gtk.Grid { software_grid.add (gtk_version_label); software_grid.add (website_label); - var hardware_view = new HardwareView (); - - var description_size_group = new Gtk.SizeGroup (Gtk.SizeGroupMode.HORIZONTAL); - description_size_group.add_widget (hardware_view); - description_size_group.add_widget (software_grid); - var description_grid = new Gtk.Grid (); description_grid.halign = Gtk.Align.CENTER; description_grid.valign = Gtk.Align.CENTER; @@ -209,8 +203,6 @@ public class About.SystemView : Gtk.Grid { description_grid.margin_start = 12; description_grid.margin_end = 12; description_grid.add (software_grid); - description_grid.add (new Gtk.Separator (Gtk.Orientation.VERTICAL)); - description_grid.add (hardware_view); add (description_grid); add (button_grid); diff --git a/src/meson.build b/src/meson.build index 178cf296b..35edbf796 100644 --- a/src/meson.build +++ b/src/meson.build @@ -14,7 +14,7 @@ plug_files = files( 'Views/FirmwareReleasesView.vala', 'Views/FirmwareView.vala', 'Views/HardwareView.vala', - 'Views/SystemView.vala' + 'Views/OperatingSystemView.vala' ) switchboard_dep = dependency('switchboard-2.0') From b2280eb591cd6a9ed20040ff52dec718fc6951f2 Mon Sep 17 00:00:00 2001 From: Marius Meisenzahl Date: Sun, 27 Dec 2020 14:36:24 +0100 Subject: [PATCH 30/96] Add list of available firmware updates --- src/Interfaces/FwupdManager.vala | 36 ++-- src/Objects/Device.vala | 1 + src/Views/FirmwareDevicePage.vala | 169 ------------------ src/Views/FirmwareDevicesView.vala | 49 ------ src/Views/FirmwareReleasePage.vala | 242 -------------------------- src/Views/FirmwareReleasesView.vala | 42 ----- src/Views/FirmwareView.vala | 81 ++++++++- src/Widgets/FirmwareUpdateWidget.vala | 83 +++++++++ src/meson.build | 7 +- 9 files changed, 176 insertions(+), 534 deletions(-) delete mode 100644 src/Views/FirmwareDevicePage.vala delete mode 100644 src/Views/FirmwareDevicesView.vala delete mode 100644 src/Views/FirmwareReleasePage.vala delete mode 100644 src/Views/FirmwareReleasesView.vala create mode 100644 src/Widgets/FirmwareUpdateWidget.vala diff --git a/src/Interfaces/FwupdManager.vala b/src/Interfaces/FwupdManager.vala index 4d64bf57c..ac4128c0b 100644 --- a/src/Interfaces/FwupdManager.vala +++ b/src/Interfaces/FwupdManager.vala @@ -23,8 +23,8 @@ extern int ro_fd (string path); [DBus (name="org.freedesktop.fwupd")] public interface About.FwupdInterface : Object { - [DBus (name = "HostProduct")] - public abstract string host_product { owned get; } + [DBus (name = "Changed")] + public signal void changed (); [DBus (name = "GetDevices")] public abstract HashTable[] get_devices () throws Error; @@ -32,19 +32,15 @@ public interface About.FwupdInterface : Object { [DBus (name = "GetReleases")] public abstract HashTable[] get_releases (string id) throws Error; - [DBus (name = "Verify")] - public abstract void verify (string id) throws Error; - [DBus (name = "Install")] public abstract void install (string id, UnixInputStream handle, HashTable options) throws Error; - - [DBus (name = "GetDetails")] - public abstract HashTable[] get_details (UnixInputStream handle) throws Error; } public class About.FwupdManager : Object { private FwupdInterface interface; + public signal void changed (); + static FwupdManager? instance = null; public static FwupdManager get_instance () { if (instance == null) { @@ -66,7 +62,12 @@ public class About.FwupdManager : Object { switch (key) { case "DeviceId": device.id = v.lookup (key).get_string (); - device.releases = get_releases (device.id); + device.flags = v.lookup ("Flags").get_uint64 (); + if (device.is (DeviceFlag.UPDATABLE)) { + device.releases = get_releases (device.id); + } else { + device.releases = new List (); + } break; case "Name": device.name = v.lookup (key).get_string (); @@ -92,9 +93,6 @@ public class About.FwupdManager : Object { case "Guid": device.guids = v.lookup (key).get_strv (); break; - case "Flags": - device.flags = v.lookup (key).get_uint64 (); - break; case "InstallDuration": device.install_duration = v.lookup (key).get_uint32 (); break; @@ -190,10 +188,6 @@ public class About.FwupdManager : Object { return releases_list; } - public void verify (string id) throws Error { - interface.verify (id); - } - private string get_path (Release release) { var parts = release.uri.split ("/"); string file_path = parts[parts.length - 1]; @@ -205,7 +199,7 @@ public class About.FwupdManager : Object { return new UnixInputStream (fd, true); } - public void install (string id, Release release) throws Error { + public void install (string id, Release release) { var handle = get_handle (release); // https://github.com/fwupd/fwupd/blob/c0d4c09a02a40167e9de57f82c0033bb92e24167/libfwupd/fwupd-client.c#L2045 @@ -220,12 +214,18 @@ public class About.FwupdManager : Object { // options.insert ("ignore-power", new Variant.boolean (true)); options.insert ("no-history", new Variant.boolean (true)); - interface.install (id, handle, options); + try { + interface.install (id, handle, options); + } catch (Error e) { + warning ("Could not connect to fwupd interface: %s", e.message); + } } construct { try { interface = Bus.get_proxy_sync (BusType.SYSTEM, "org.freedesktop.fwupd", "/"); + + interface.changed.connect (() => { changed (); }); } catch (Error e) { warning ("Could not connect to fwupd interface: %s", e.message); } diff --git a/src/Objects/Device.vala b/src/Objects/Device.vala index 7e327fe31..f77c3d97b 100644 --- a/src/Objects/Device.vala +++ b/src/Objects/Device.vala @@ -32,6 +32,7 @@ public class About.Device : Object { public string update_error { get; set; } public List releases { get; owned set; } + public Release latest_release { get { return releases.nth_data (0); }} public bool is (DeviceFlag flag) { foreach (var f in DeviceFlag.get_list (flags)) { diff --git a/src/Views/FirmwareDevicePage.vala b/src/Views/FirmwareDevicePage.vala deleted file mode 100644 index a1ad0d379..000000000 --- a/src/Views/FirmwareDevicePage.vala +++ /dev/null @@ -1,169 +0,0 @@ -/* -* Copyright (c) 2020 elementary, Inc. (https://elementary.io) -* -* 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 3 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 -* -* Authored by: Marius Meisenzahl -*/ - -public class About.FirmwareDevicePage : Granite.SimpleSettingsPage { - private Gtk.Label version_value_label; - private Gtk.Label vendor_value_label; - private Gtk.Grid guids_grid; - private Gtk.Grid flags_grid; - private Gtk.Label update_error_value_label; - private Gtk.Label install_duration_value_label; - - private Gtk.Button verify_button; - private Gtk.Button show_releases_button; - - public signal void verify (string device_id); - public signal void show_releases (Device device); - - public FirmwareDevicePage (Device device) { - Object ( - icon_name: device.icon, - status: device.summary, - title: device.name - ); - - version_value_label.label = device.version; - - vendor_value_label.label = device.vendor; - - foreach (var guid in device.guids) { - var label = new Gtk.Label (guid) { - xalign = 0, - hexpand = true - }; - guids_grid.add (label); - } - - foreach (var device_flag in DeviceFlag.get_list (device.flags)) { - var name = device_flag.to_string (); - - if (name != null) { - var icon = new Gtk.Image () { - gicon = new ThemedIcon (device_flag.to_icon ()), - pixel_size = 16 - }; - var label = new Gtk.Label (name) { - xalign = 0, - hexpand = true - }; - var grid = new Gtk.Grid () { - orientation = Gtk.Orientation.HORIZONTAL, - column_spacing = 8 - }; - - grid.add (icon); - grid.add (label); - - flags_grid.add (grid); - } - } - - update_error_value_label.label = device.update_error; - - install_duration_value_label.label = Formatter.seconds_to_string (device.install_duration); - - verify_button.sensitive = device.releases.length () > 0; - verify_button.clicked.connect (() => { - verify (device.id); - }); - - show_releases_button.sensitive = device.releases.length () > 0; - show_releases_button.clicked.connect (() => { - show_releases (device); - }); - } - - construct { - var version_label = new Gtk.Label (_("Current Version:")) { - xalign = 1 - }; - - version_value_label = new Gtk.Label ("") { - xalign = 0, - hexpand = true - }; - - var vendor_label = new Gtk.Label (_("Vendor:")) { - xalign = 1 - }; - - vendor_value_label = new Gtk.Label ("") { - xalign = 0, - hexpand = true - }; - - var guids_label = new Gtk.Label (_("GUIDs:")) { - xalign = 1, - yalign = 0 - }; - - guids_grid = new Gtk.Grid () { - orientation = Gtk.Orientation.VERTICAL - }; - - var flags_label = new Gtk.Label (_("Flags:")) { - xalign = 1, - yalign = 0 - }; - - flags_grid = new Gtk.Grid () { - orientation = Gtk.Orientation.VERTICAL, - row_spacing = 4 - }; - - var update_error_label = new Gtk.Label (_("Update Error:")) { - xalign = 1 - }; - - update_error_value_label = new Gtk.Label ("") { - xalign = 0, - hexpand = true - }; - - var install_duration_label = new Gtk.Label (_("Install Duration:")) { - xalign = 1 - }; - - install_duration_value_label = new Gtk.Label ("") { - xalign = 0, - hexpand = true - }; - - content_area.attach (version_label, 0, 1, 1, 1); - content_area.attach (version_value_label, 1, 1, 1, 1); - content_area.attach (vendor_label, 0, 2, 1, 1); - content_area.attach (vendor_value_label, 1, 2, 1, 1); - content_area.attach (guids_label, 0, 3, 1, 1); - content_area.attach (guids_grid, 1, 3, 1, 1); - content_area.attach (flags_label, 0, 4, 1, 1); - content_area.attach (flags_grid, 1, 4, 1, 1); - content_area.attach (update_error_label, 0, 5, 1, 1); - content_area.attach (update_error_value_label, 1, 5, 1, 1); - content_area.attach (install_duration_label, 0, 6, 1, 1); - content_area.attach (install_duration_value_label, 1, 6, 1, 1); - - verify_button = new Gtk.Button.with_label (_("Verify")); - show_releases_button = new Gtk.Button.with_label (_("Show Releases")); - - action_area.add (verify_button); - action_area.add (show_releases_button); - } -} diff --git a/src/Views/FirmwareDevicesView.vala b/src/Views/FirmwareDevicesView.vala deleted file mode 100644 index abfe05088..000000000 --- a/src/Views/FirmwareDevicesView.vala +++ /dev/null @@ -1,49 +0,0 @@ -/* -* Copyright (c) 2020 elementary, Inc. (https://elementary.io) -* -* 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 3 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 -* -* Authored by: Marius Meisenzahl -*/ - -public class About.FirmwareDevicesView : Gtk.Paned { - public signal void verify (string device_id); - public signal void show_releases (Device device); - - construct { - var stack = new Gtk.Stack (); - - var fwupd_manager = FwupdManager.get_instance (); - foreach (var device in fwupd_manager.get_devices ()) { - if (device.is (DeviceFlag.UPDATABLE)) { - var page = new FirmwareDevicePage (device); - page.verify.connect ((device_id) => { - verify (device_id); - }); - page.show_releases.connect ((device) => { - show_releases (device); - }); - - stack.add_named (page, device.id); - } - } - - var settings_sidebar = new Granite.SettingsSidebar (stack); - - add (settings_sidebar); - add (stack); - } -} diff --git a/src/Views/FirmwareReleasePage.vala b/src/Views/FirmwareReleasePage.vala deleted file mode 100644 index ad7e61a5e..000000000 --- a/src/Views/FirmwareReleasePage.vala +++ /dev/null @@ -1,242 +0,0 @@ -/* -* Copyright (c) 2020 elementary, Inc. (https://elementary.io) -* -* 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 3 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 -* -* Authored by: Marius Meisenzahl -*/ - -public class About.FirmwareReleasePage : Granite.SimpleSettingsPage { - private Gtk.Label version_value_label; - private Gtk.Label summary_value_label; - private Gtk.Label description_value_label; - private Gtk.Label filename_value_label; - private Gtk.Label protocol_value_label; - private Gtk.Label remote_id_value_label; - private Gtk.Label appstream_id_value_label; - private Gtk.Label checksum_value_label; - private Gtk.Label vendor_value_label; - private Gtk.Label size_value_label; - private Gtk.Label license_value_label; - private Gtk.Label install_duration_value_label; - - public FirmwareReleasePage (Device device, Release release) { - Object ( - icon_name: release.icon, - status: release.summary, - title: release.name - ); - - version_value_label.label = release.version; - - summary_value_label.label = release.summary; - - description_value_label.label = release.description; - - filename_value_label.label = release.filename; - - protocol_value_label.label = release.protocol; - - remote_id_value_label.label = release.remote_id; - - appstream_id_value_label.label = release.appstream_id; - - checksum_value_label.label = release.checksum; - - vendor_value_label.label = release.vendor; - - size_value_label.label = Formatter.bytes_to_string (release.size); - - license_value_label.label = release.license; - - install_duration_value_label.label = Formatter.seconds_to_string (release.install_duration); - - var message_dialog = new Granite.MessageDialog.with_image_from_icon_name ( - _("%s firmware version %s").printf (release.name, release.version), - _("Install this firmware file?"), - "security-high", - Gtk.ButtonsType.CANCEL - ); - - var suggested_button = new Gtk.Button.with_label (_("Install")); - suggested_button.get_style_context ().add_class (Gtk.STYLE_CLASS_SUGGESTED_ACTION); - message_dialog.add_action_widget (suggested_button, Gtk.ResponseType.ACCEPT); - - var button = new Gtk.Button (); - - switch (release.flag) { - case ReleaseFlag.IS_UPGRADE: - button.label = _("Install Upgrade"); - break; - case ReleaseFlag.IS_DOWNGRADE: - button.label = _("Install Downgrade"); - break; - default: - button.label = _("Reinstall"); - suggested_button.label = _("Reinstall"); - message_dialog.secondary_text = _("This firmware version is already installed on the device. Reinstall this firmware file?"); - break; - } - - button.clicked.connect (() => { - message_dialog.show_all (); - if (message_dialog.run () == Gtk.ResponseType.ACCEPT) { - FwupdManager.get_instance ().install (device.id, release); - } - - message_dialog.destroy (); - }); - - action_area.add (button); - } - - construct { - var version_label = new Gtk.Label (_("Version:")) { - xalign = 1 - }; - - version_value_label = new Gtk.Label ("") { - xalign = 0, - hexpand = true - }; - - var summary_label = new Gtk.Label (_("Summary:")) { - xalign = 1 - }; - - summary_value_label = new Gtk.Label ("") { - xalign = 0, - hexpand = true - }; - - var description_label = new Gtk.Label (_("Description:")) { - xalign = 1, - yalign = 0 - }; - - description_value_label = new Gtk.Label ("") { - xalign = 0, - hexpand = true, - wrap = true - }; - - var filename_label = new Gtk.Label (_("Filename:")) { - xalign = 1 - }; - - filename_value_label = new Gtk.Label ("") { - xalign = 0, - hexpand = true - }; - - var protocol_label = new Gtk.Label (_("Protocol:")) { - xalign = 1 - }; - - protocol_value_label = new Gtk.Label ("") { - xalign = 0, - hexpand = true - }; - - var remote_id_label = new Gtk.Label (_("Remote ID:")) { - xalign = 1 - }; - - remote_id_value_label = new Gtk.Label ("") { - xalign = 0, - hexpand = true - }; - - var appstream_id_label = new Gtk.Label (_("Appstream ID:")) { - xalign = 1 - }; - - appstream_id_value_label = new Gtk.Label ("") { - xalign = 0, - hexpand = true - }; - - var checksum_label = new Gtk.Label (_("Checksum:")) { - xalign = 1 - }; - - checksum_value_label = new Gtk.Label ("") { - xalign = 0, - hexpand = true - }; - - var vendor_label = new Gtk.Label (_("Vendor:")) { - xalign = 1 - }; - - vendor_value_label = new Gtk.Label ("") { - xalign = 0, - hexpand = true - }; - - var size_label = new Gtk.Label (_("Size:")) { - xalign = 1 - }; - - size_value_label = new Gtk.Label ("") { - xalign = 0, - hexpand = true - }; - - var license_label = new Gtk.Label (_("License:")) { - xalign = 1 - }; - - license_value_label = new Gtk.Label ("") { - xalign = 0, - hexpand = true - }; - - var install_duration_label = new Gtk.Label (_("Install Duration:")) { - xalign = 1 - }; - - install_duration_value_label = new Gtk.Label ("") { - xalign = 0, - hexpand = true - }; - - content_area.attach (version_label, 0, 1, 1, 1); - content_area.attach (version_value_label, 1, 1, 1, 1); - content_area.attach (summary_label, 0, 2, 1, 1); - content_area.attach (summary_value_label, 1, 2, 1, 1); - content_area.attach (description_label, 0, 3, 1, 1); - content_area.attach (description_value_label, 1, 3, 1, 1); - content_area.attach (filename_label, 0, 4, 1, 1); - content_area.attach (filename_value_label, 1, 4, 1, 1); - content_area.attach (protocol_label, 0, 5, 1, 1); - content_area.attach (protocol_value_label, 1, 5, 1, 1); - content_area.attach (remote_id_label, 0, 6, 1, 1); - content_area.attach (remote_id_value_label, 1, 6, 1, 1); - content_area.attach (appstream_id_label, 0, 7, 1, 1); - content_area.attach (appstream_id_value_label, 1, 7, 1, 1); - content_area.attach (checksum_label, 0, 8, 1, 1); - content_area.attach (checksum_value_label, 1, 8, 1, 1); - content_area.attach (vendor_label, 0, 9, 1, 1); - content_area.attach (vendor_value_label, 1, 9, 1, 1); - content_area.attach (size_label, 0, 10, 1, 1); - content_area.attach (size_value_label, 1, 10, 1, 1); - content_area.attach (license_label, 0, 11, 1, 1); - content_area.attach (license_value_label, 1, 11, 1, 1); - content_area.attach (install_duration_label, 0, 12, 1, 1); - content_area.attach (install_duration_value_label, 1, 12, 1, 1); - } -} diff --git a/src/Views/FirmwareReleasesView.vala b/src/Views/FirmwareReleasesView.vala deleted file mode 100644 index d409ad2de..000000000 --- a/src/Views/FirmwareReleasesView.vala +++ /dev/null @@ -1,42 +0,0 @@ -/* -* Copyright (c) 2020 elementary, Inc. (https://elementary.io) -* -* 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 3 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 -* -* Authored by: Marius Meisenzahl -*/ - -public class About.FirmwareReleasesView : Gtk.Paned { - public void get_releases (Device device) { - foreach (Gtk.Widget element in get_children ()) { - remove (element); - } - - var stack = new Gtk.Stack (); - - foreach (var release in device.releases) { - var page = new FirmwareReleasePage (device, release); - - stack.add_named (page, release.filename); - } - - var settings_sidebar = new Granite.SettingsSidebar (stack); - - add (settings_sidebar); - add (stack); - show_all (); - } -} diff --git a/src/Views/FirmwareView.vala b/src/Views/FirmwareView.vala index 1ff3a9c3c..157c20300 100644 --- a/src/Views/FirmwareView.vala +++ b/src/Views/FirmwareView.vala @@ -19,17 +19,80 @@ * Authored by: Marius Meisenzahl */ -public class About.FirmwareView : Gtk.Stack { +public class About.FirmwareView : Granite.SettingsPage { + private Gtk.Button update_all_button; + private Gtk.ListBox update_list; + + public FirmwareView () { + Object ( + icon_name: "application-x-firmware", + title: _("Firmware") + ); + } + construct { - var firmware_devices_view = new FirmwareDevicesView (); - var firmware_releases_view = new FirmwareReleasesView (); + var header_icon = new Gtk.Image.from_icon_name ("application-x-firmware", Gtk.IconSize.DIALOG) { + pixel_size = 48, + valign = Gtk.Align.START + }; + + var title_label = new Gtk.Label (_("Firmware")) { + ellipsize = Pango.EllipsizeMode.END, + selectable = true, + xalign = 0 + }; + title_label.get_style_context ().add_class (Granite.STYLE_CLASS_H2_LABEL); + + update_all_button = new Gtk.Button.with_label (_("Update All")) { + hexpand = true, + halign = Gtk.Align.END, + valign = Gtk.Align.CENTER, + sensitive = false + }; + + var grid = new Gtk.Grid () { + column_spacing = 12, + row_spacing = 12, + margin = 12 + }; + + update_list = new Gtk.ListBox () { + vexpand = true, + selection_mode = Gtk.SelectionMode.SINGLE + }; + + var scrolled_window = new Gtk.ScrolledWindow (null, null); + scrolled_window.add (update_list); + + var frame = new Gtk.Frame (null); + frame.add (scrolled_window); + + grid.attach (header_icon, 0, 0); + grid.attach (title_label, 1, 0); + grid.attach (update_all_button, 2, 0); + grid.attach (frame, 0, 1, 3, 1); + + add (grid); + + FwupdManager.get_instance ().changed.connect (update_list_view); + + update_list_view (); + } + + private void update_list_view () { + foreach (Gtk.Widget element in update_list.get_children ()) { + if (element is Gtk.ListBoxRow) { + update_list.remove (element); + } + } - firmware_devices_view.show_releases.connect ((device) => { - firmware_releases_view.get_releases (device); - set_visible_child_name ("releases"); - }); + foreach (var device in FwupdManager.get_instance ().get_devices ()) { + if (device.is (DeviceFlag.UPDATABLE) && device.releases.length () > 0) { + var widget = new Widgets.FirmwareUpdateWidget (device); + update_list.add (widget); + } + } - add_named (firmware_devices_view, "devices"); - add_named (firmware_releases_view, "releases"); + update_list.show_all (); } } diff --git a/src/Widgets/FirmwareUpdateWidget.vala b/src/Widgets/FirmwareUpdateWidget.vala new file mode 100644 index 000000000..67251980c --- /dev/null +++ b/src/Widgets/FirmwareUpdateWidget.vala @@ -0,0 +1,83 @@ +/* +* Copyright 2020 elementary, Inc. (https://elementary.io) +* +* 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 3 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 +* +* Authored by: Marius Meisenzahl +*/ + +public class About.Widgets.FirmwareUpdateWidget : Gtk.ListBoxRow { + public Device device { get; construct set; } + + public FirmwareUpdateWidget (Device device) { + GLib.Object ( + device: device + ); + } + + construct { + var icon = new Gtk.Image.from_icon_name (device.icon, Gtk.IconSize.DND) { + pixel_size = 32 + }; + + var device_name_label = new Gtk.Label (device.name) { + halign = Gtk.Align.START, + hexpand = true + }; + device_name_label.get_style_context ().add_class (Granite.STYLE_CLASS_H3_LABEL); + + var version_label = new Gtk.Label (device.latest_release.version) { + wrap = true, + xalign = 0 + }; + + var grid = new Gtk.Grid (); + grid.column_spacing = 12; + grid.margin = 6; + grid.attach (icon, 0, 0, 1, 2); + grid.attach (device_name_label, 1, 0); + grid.attach (version_label, 1, 1); + + switch (device.latest_release.flag) { + case ReleaseFlag.IS_UPGRADE: + if (device.latest_release.version == device.version) { + add_up_to_date_label (grid); + break; + } + + var update_button = new Gtk.Button.with_label (_("Update")) { + valign = Gtk.Align.CENTER + }; + update_button.clicked.connect (() => { + FwupdManager.get_instance ().install (device.id, device.latest_release); + }); + grid.attach (update_button, 2, 0, 1, 2); + break; + default: + add_up_to_date_label (grid); + break; + } + + add (grid); + } + + private void add_up_to_date_label (Gtk.Grid grid) { + var update_to_date_label = new Gtk.Label (_("Up to date")) { + valign = Gtk.Align.CENTER + }; + grid.attach (update_to_date_label, 2, 0, 1, 2); + } +} diff --git a/src/meson.build b/src/meson.build index 35edbf796..58b42cfa6 100644 --- a/src/meson.build +++ b/src/meson.build @@ -8,13 +8,10 @@ plug_files = files( 'Interfaces/FwupdManager.vala', 'Utils/ARMPartDecoder.vala', 'Utils/Formatter.vala', - 'Views/FirmwareDevicePage.vala', - 'Views/FirmwareDevicesView.vala', - 'Views/FirmwareReleasePage.vala', - 'Views/FirmwareReleasesView.vala', 'Views/FirmwareView.vala', 'Views/HardwareView.vala', - 'Views/OperatingSystemView.vala' + 'Views/OperatingSystemView.vala', + 'Widgets/FirmwareUpdateWidget.vala' ) switchboard_dep = dependency('switchboard-2.0') From 8ee28c84058beeba945887d03a3502ff4a945910 Mon Sep 17 00:00:00 2001 From: Marius Meisenzahl Date: Sun, 27 Dec 2020 16:03:50 +0100 Subject: [PATCH 31/96] Download update --- src/Interfaces/FwupdManager.vala | 26 ++++++++++++++++++++++---- src/Views/FirmwareView.vala | 4 ++-- src/Widgets/FirmwareUpdateWidget.vala | 3 +++ 3 files changed, 27 insertions(+), 6 deletions(-) diff --git a/src/Interfaces/FwupdManager.vala b/src/Interfaces/FwupdManager.vala index ac4128c0b..4f557590c 100644 --- a/src/Interfaces/FwupdManager.vala +++ b/src/Interfaces/FwupdManager.vala @@ -191,16 +191,34 @@ public class About.FwupdManager : Object { private string get_path (Release release) { var parts = release.uri.split ("/"); string file_path = parts[parts.length - 1]; - return Path.build_path (Path.DIR_SEPARATOR_S, Path.DIR_SEPARATOR_S, "tmp", file_path); + return Path.build_path (Path.DIR_SEPARATOR_S, Environment.get_tmp_dir (), file_path); } - private UnixInputStream get_handle (Release release) { - var fd = ro_fd (get_path (release)); + private UnixInputStream get_handle (string path) { + var fd = ro_fd (path); return new UnixInputStream (fd, true); } public void install (string id, Release release) { - var handle = get_handle (release); + var path = get_path (release); + + File server_file = File.new_for_uri (release.uri); + File local_file = File.new_for_path (path); + + bool result; + try { + result = server_file.copy (local_file, FileCopyFlags.OVERWRITE); + } catch (Error e) { + warning ("Could not download file: %s", e.message); + return; + } + + if (!result) { + warning ("Download of %s was not succesfull", release.uri); + return; + } + + var handle = get_handle (path); // https://github.com/fwupd/fwupd/blob/c0d4c09a02a40167e9de57f82c0033bb92e24167/libfwupd/fwupd-client.c#L2045 HashTable options = new HashTable (str_hash, str_equal); diff --git a/src/Views/FirmwareView.vala b/src/Views/FirmwareView.vala index 157c20300..9000415df 100644 --- a/src/Views/FirmwareView.vala +++ b/src/Views/FirmwareView.vala @@ -74,8 +74,6 @@ public class About.FirmwareView : Granite.SettingsPage { add (grid); - FwupdManager.get_instance ().changed.connect (update_list_view); - update_list_view (); } @@ -90,6 +88,8 @@ public class About.FirmwareView : Granite.SettingsPage { if (device.is (DeviceFlag.UPDATABLE) && device.releases.length () > 0) { var widget = new Widgets.FirmwareUpdateWidget (device); update_list.add (widget); + + widget.on_updated.connect (update_list_view); } } diff --git a/src/Widgets/FirmwareUpdateWidget.vala b/src/Widgets/FirmwareUpdateWidget.vala index 67251980c..ead3d6799 100644 --- a/src/Widgets/FirmwareUpdateWidget.vala +++ b/src/Widgets/FirmwareUpdateWidget.vala @@ -22,6 +22,8 @@ public class About.Widgets.FirmwareUpdateWidget : Gtk.ListBoxRow { public Device device { get; construct set; } + public signal void on_updated (); + public FirmwareUpdateWidget (Device device) { GLib.Object ( device: device @@ -63,6 +65,7 @@ public class About.Widgets.FirmwareUpdateWidget : Gtk.ListBoxRow { }; update_button.clicked.connect (() => { FwupdManager.get_instance ().install (device.id, device.latest_release); + on_updated (); }); grid.attach (update_button, 2, 0, 1, 2); break; From 7a9c113f0f038f2ea9cfcaed0aed1491cc285ba1 Mon Sep 17 00:00:00 2001 From: Marius Meisenzahl Date: Sun, 27 Dec 2020 16:29:57 +0100 Subject: [PATCH 32/96] Remove unused code --- src/Utils/Formatter.vala | 57 ---------------------------------------- src/meson.build | 1 - 2 files changed, 58 deletions(-) delete mode 100644 src/Utils/Formatter.vala diff --git a/src/Utils/Formatter.vala b/src/Utils/Formatter.vala deleted file mode 100644 index 8c8473a54..000000000 --- a/src/Utils/Formatter.vala +++ /dev/null @@ -1,57 +0,0 @@ -/* -* Copyright (c) 2020 elementary, Inc. (https://elementary.io) -* -* 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 3 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 -* -* Authored by: Marius Meisenzahl -*/ - -public class About.Formatter : Granite.SimpleSettingsPage { - public static string bytes_to_string (uint64 bytes) { - if (bytes > 1000000000) { - return "%.1f GB".printf (bytes / 1000000000.0); - } else if (bytes > 1000000) { - return "%.1f MB".printf (bytes / 1000000.0); - } else if (bytes > 1000) { - return "%.1f kB".printf (bytes / 1000.0); - } - - return "%llu B".printf (bytes); - } - - public static string? seconds_to_string (uint64 seconds) { - uint64 minutes, hours; - - if (seconds == 0) { - return null; - } - - if (seconds >= 60) { - minutes = seconds / 60; - seconds = seconds % 60; - - if (minutes >= 60) { - hours = minutes / 60; - minutes = minutes % 60; - return _("%llu hr, %llu min, %llu sec").printf (hours, minutes, seconds); - } - - return _("%llu min, %llu sec").printf (minutes, seconds); - } - - return _("%llu sec").printf (seconds); - } -} diff --git a/src/meson.build b/src/meson.build index 58b42cfa6..0225025c4 100644 --- a/src/meson.build +++ b/src/meson.build @@ -7,7 +7,6 @@ plug_files = files( 'Objects/ReleaseFlag.vala', 'Interfaces/FwupdManager.vala', 'Utils/ARMPartDecoder.vala', - 'Utils/Formatter.vala', 'Views/FirmwareView.vala', 'Views/HardwareView.vala', 'Views/OperatingSystemView.vala', From 5d4dbd802940977983e2daafb016b3935d05fc9c Mon Sep 17 00:00:00 2001 From: Marius Meisenzahl Date: Tue, 29 Dec 2020 14:31:54 +0100 Subject: [PATCH 33/96] Refactor --- src/Objects/DeviceFlag.vala | 4 ++-- src/Objects/ReleaseFlag.vala | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Objects/DeviceFlag.vala b/src/Objects/DeviceFlag.vala index 6bacee6e4..9b44ff303 100644 --- a/src/Objects/DeviceFlag.vala +++ b/src/Objects/DeviceFlag.vala @@ -64,7 +64,7 @@ public enum About.DeviceFlag { HAS_MULTIPLE_BRANCHES = (1u << 39), /* Since: 1.5.0 */ BACKUP_BEFORE_INSTALL = (1u << 40), /* Since: 1.5.0 */ MD_SET_ICON = (1u << 41), /* Since: 1.5.2 */ - UNKNOWN = 18446744073709551615; /* Since: 0.7.3 */ // using uint64.max --> ‘MAX’ undeclared here (not in a function) + UNKNOWN = uint64.MAX; /* Since: 0.7.3 */ public static List get_list (uint64 flags) { var list = new List (); @@ -198,7 +198,7 @@ public enum About.DeviceFlag { if ((flags & (1u << 41)) > 0) { list.append (DeviceFlag.MD_SET_ICON); } - if ((flags & (18446744073709551615)) > 0) { + if ((flags & (uint64.MAX)) > 0) { list.append (DeviceFlag.UNKNOWN); } diff --git a/src/Objects/ReleaseFlag.vala b/src/Objects/ReleaseFlag.vala index 0746279d6..230db4e0c 100644 --- a/src/Objects/ReleaseFlag.vala +++ b/src/Objects/ReleaseFlag.vala @@ -29,7 +29,7 @@ public enum About.ReleaseFlag { BLOCKED_VERSION = (1u << 4), /* Since: 1.2.6 */ BLOCKED_APPROVAL = (1u << 5), /* Since: 1.2.6 */ IS_ALTERNATE_BRANCH = (1u << 6), /* Since: 1.5.0 */ - UNKNOWN = 18446744073709551615; /* Since: 1.2.6 */ // using uint64.max --> ‘MAX’ undeclared here (not in a function) + UNKNOWN = uint64.MAX; /* Since: 1.2.6 */ public static ReleaseFlag from_uint64 (uint64 flag) { if ((flag & (0u)) > 0) { From b48aee4a1df1206264d83cecc7b70a9035c3195e Mon Sep 17 00:00:00 2001 From: Marius Meisenzahl Date: Tue, 29 Dec 2020 14:48:33 +0100 Subject: [PATCH 34/96] Make calls async --- src/Interfaces/FwupdManager.vala | 177 ++++++++++++++++---------- src/Views/FirmwareView.vala | 6 +- src/Widgets/FirmwareUpdateWidget.vala | 8 +- 3 files changed, 119 insertions(+), 72 deletions(-) diff --git a/src/Interfaces/FwupdManager.vala b/src/Interfaces/FwupdManager.vala index 4f557590c..f5220d8eb 100644 --- a/src/Interfaces/FwupdManager.vala +++ b/src/Interfaces/FwupdManager.vala @@ -21,23 +21,8 @@ extern int ro_fd (string path); -[DBus (name="org.freedesktop.fwupd")] -public interface About.FwupdInterface : Object { - [DBus (name = "Changed")] - public signal void changed (); - - [DBus (name = "GetDevices")] - public abstract HashTable[] get_devices () throws Error; - - [DBus (name = "GetReleases")] - public abstract HashTable[] get_releases (string id) throws Error; - - [DBus (name = "Install")] - public abstract void install (string id, UnixInputStream handle, HashTable options) throws Error; -} - public class About.FwupdManager : Object { - private FwupdInterface interface; + private DBusConnection connection; public signal void changed (); @@ -52,52 +37,73 @@ public class About.FwupdManager : Object { private FwupdManager () {} - public List get_devices () { + public async List get_devices () { var devices_list = new List (); try { - foreach (var v in interface.get_devices ()) { + var result = yield connection.call ( + "org.freedesktop.fwupd", + "/", + "org.freedesktop.fwupd", + "GetDevices", + null, + new VariantType ("(aa{sv})"), + DBusCallFlags.NONE, + -1 + ); + + var array_iter = result.iterator (); + GLib.Variant? element = array_iter.next_value (); + array_iter = element.iterator (); + + while ((element = array_iter.next_value ()) != null) { + GLib.Variant? val = null; + string? key = null; + + var device_iter = element.iterator (); var device = new Device (); - foreach (var key in v.get_keys ()) { + while (device_iter.next ("{sv}", out key, out val)) { switch (key) { case "DeviceId": - device.id = v.lookup (key).get_string (); - device.flags = v.lookup ("Flags").get_uint64 (); - if (device.is (DeviceFlag.UPDATABLE)) { - device.releases = get_releases (device.id); + device.id = val.get_string (); + break; + case "Flags": + device.flags = val.get_uint64 (); + if (device.id.length > 0 && device.is (DeviceFlag.UPDATABLE)) { + device.releases = yield get_releases (device.id); } else { device.releases = new List (); } break; case "Name": - device.name = v.lookup (key).get_string (); + device.name = val.get_string (); break; case "Summary": - device.summary = v.lookup (key).get_string (); + device.summary = val.get_string (); break; case "Vendor": - device.vendor = v.lookup (key).get_string (); + device.vendor = val.get_string (); break; case "VendorId": if (device.vendor == null) { - device.vendor = v.lookup (key).get_string (); + device.vendor = val.get_string (); } break; case "Version": - device.version = v.lookup (key).get_string (); + device.version = val.get_string (); break; case "Icon": - var icons = v.lookup (key).get_strv (); + var icons = val.get_strv (); device.icon = icons.length > 0 ? icons[0] : "application-x-firmware"; break; case "Guid": - device.guids = v.lookup (key).get_strv (); + device.guids = val.get_strv (); break; case "InstallDuration": - device.install_duration = v.lookup (key).get_uint32 (); + device.install_duration = val.get_uint32 (); break; case "UpdateError": - device.update_error = v.lookup (key).get_string (); + device.update_error = val.get_string (); break; default: break; @@ -112,29 +118,51 @@ public class About.FwupdManager : Object { return devices_list; } - private List get_releases (string id) { + private async List get_releases (string id) { var releases_list = new List (); try { - foreach (var v in interface.get_releases (id)) { + var result = yield connection.call ( + "org.freedesktop.fwupd", + "/", + "org.freedesktop.fwupd", + "GetReleases", + new Variant ( + "(s)", + id + ), + new VariantType ("(aa{sv})"), + DBusCallFlags.NONE, + -1 + ); + + var array_iter = result.iterator (); + GLib.Variant? element = array_iter.next_value (); + array_iter = element.iterator (); + + while ((element = array_iter.next_value ()) != null) { + GLib.Variant? val = null; + string? key = null; + + var release_iter = element.iterator (); var release = new Release (); release.icon = "security-high"; - foreach (var key in v.get_keys ()) { + while (release_iter.next ("{sv}", out key, out val)) { switch (key) { case "Filename": - release.filename = v.lookup (key).get_string (); + release.filename = val.get_string (); break; case "Name": - release.name = v.lookup (key).get_string (); + release.name = val.get_string (); break; case "Summary": - release.summary = v.lookup (key).get_string (); + release.summary = val.get_string (); break; case "Version": - release.version = v.lookup (key).get_string (); + release.version = val.get_string (); break; case "Description": - release.description = v.lookup (key).get_string () + release.description = val.get_string () .replace ("

      ", "") .replace ("

      ", "\n\n") .replace ("
    1. ", " • ") @@ -146,34 +174,34 @@ public class About.FwupdManager : Object { .strip (); break; case "Protocol": - release.protocol = v.lookup (key).get_string (); + release.protocol = val.get_string (); break; case "RemoteId": - release.remote_id = v.lookup (key).get_string (); + release.remote_id = val.get_string (); break; case "AppstreamId": - release.appstream_id = v.lookup (key).get_string (); + release.appstream_id = val.get_string (); break; case "Checksum": - release.checksum = v.lookup (key).get_string (); + release.checksum = val.get_string (); break; case "Vendor": - release.vendor = v.lookup (key).get_string (); + release.vendor = val.get_string (); break; case "Size": - release.size = v.lookup (key).get_uint64 (); + release.size = val.get_uint64 (); break; case "License": - release.license = v.lookup (key).get_string (); + release.license = val.get_string (); break; case "TrustFlags": - release.flag = ReleaseFlag.from_uint64 (v.lookup (key).get_uint64 ()); + release.flag = ReleaseFlag.from_uint64 (val.get_uint64 ()); break; case "InstallDuration": - release.install_duration = v.lookup (key).get_uint32 (); + release.install_duration = val.get_uint32 (); break; case "Uri": - release.uri = v.lookup (key).get_string (); + release.uri = val.get_string (); break; default: break; @@ -199,7 +227,7 @@ public class About.FwupdManager : Object { return new UnixInputStream (fd, true); } - public void install (string id, Release release) { + public async void install (string id, Release release) { var path = get_path (release); File server_file = File.new_for_uri (release.uri); @@ -207,7 +235,10 @@ public class About.FwupdManager : Object { bool result; try { - result = server_file.copy (local_file, FileCopyFlags.OVERWRITE); + result = yield server_file.copy_async (local_file, FileCopyFlags.OVERWRITE, Priority.DEFAULT, null, (current_num_bytes, total_num_bytes) => { + debug ("%" + int64.FORMAT + " bytes of %" + int64.FORMAT + " bytes copied.", + current_num_bytes, release.size); + }); } catch (Error e) { warning ("Could not download file: %s", e.message); return; @@ -221,19 +252,33 @@ public class About.FwupdManager : Object { var handle = get_handle (path); // https://github.com/fwupd/fwupd/blob/c0d4c09a02a40167e9de57f82c0033bb92e24167/libfwupd/fwupd-client.c#L2045 - HashTable options = new HashTable (str_hash, str_equal); - options.insert ("reason", new Variant.string ("user-action")); - options.insert ("filename", new Variant.string (get_path (release))); - // options.insert ("offline", new Variant.boolean (true)); - options.insert ("allow-older", new Variant.boolean (true)); - options.insert ("allow-reinstall", new Variant.boolean (true)); - // options.insert ("allow-branch-switch", new Variant.boolean (true)); - // options.insert ("force", new Variant.boolean (true)); - // options.insert ("ignore-power", new Variant.boolean (true)); - options.insert ("no-history", new Variant.boolean (true)); + var options = new VariantBuilder (new VariantType ("a{sv}")); + options.add ("{sv}", "reason", new Variant.string ("user-action")); + options.add ("{sv}", "filename", new Variant.string (path)); + // options.add ("{sv}", "offline", new Variant.boolean (true)); + options.add ("{sv}", "allow-older", new Variant.boolean (true)); + options.add ("{sv}", "allow-reinstall", new Variant.boolean (true)); + // options.add ("{sv}", "allow-branch-switch", new Variant.boolean (true)); + // options.add ("{sv}", "force", new Variant.boolean (true)); + // options.add ("{sv}", "ignore-power", new Variant.boolean (true)); + options.add ("{sv}", "no-history", new Variant.boolean (true)); + + var parameters = new VariantBuilder (new VariantType ("(sha{sv})")); + parameters.add_value (new Variant.string (id)); + parameters.add_value (new Variant.handle (handle.fd)); + parameters.add_value (options.end ()); try { - interface.install (id, handle, options); + yield connection.call ( + "org.freedesktop.fwupd", + "/", + "org.freedesktop.fwupd", + "Install", + parameters.end (), + null, + DBusCallFlags.NONE, + -1 + ); } catch (Error e) { warning ("Could not connect to fwupd interface: %s", e.message); } @@ -241,11 +286,9 @@ public class About.FwupdManager : Object { construct { try { - interface = Bus.get_proxy_sync (BusType.SYSTEM, "org.freedesktop.fwupd", "/"); - - interface.changed.connect (() => { changed (); }); + connection = Bus.get_sync (BusType.SYSTEM); } catch (Error e) { - warning ("Could not connect to fwupd interface: %s", e.message); + warning ("Could not connect to system bus: %s", e.message); } } } diff --git a/src/Views/FirmwareView.vala b/src/Views/FirmwareView.vala index 9000415df..45cada5b5 100644 --- a/src/Views/FirmwareView.vala +++ b/src/Views/FirmwareView.vala @@ -74,17 +74,17 @@ public class About.FirmwareView : Granite.SettingsPage { add (grid); - update_list_view (); + update_list_view.begin (); } - private void update_list_view () { + private async void update_list_view () { foreach (Gtk.Widget element in update_list.get_children ()) { if (element is Gtk.ListBoxRow) { update_list.remove (element); } } - foreach (var device in FwupdManager.get_instance ().get_devices ()) { + foreach (var device in yield FwupdManager.get_instance ().get_devices ()) { if (device.is (DeviceFlag.UPDATABLE) && device.releases.length () > 0) { var widget = new Widgets.FirmwareUpdateWidget (device); update_list.add (widget); diff --git a/src/Widgets/FirmwareUpdateWidget.vala b/src/Widgets/FirmwareUpdateWidget.vala index ead3d6799..6e4732e14 100644 --- a/src/Widgets/FirmwareUpdateWidget.vala +++ b/src/Widgets/FirmwareUpdateWidget.vala @@ -64,8 +64,12 @@ public class About.Widgets.FirmwareUpdateWidget : Gtk.ListBoxRow { valign = Gtk.Align.CENTER }; update_button.clicked.connect (() => { - FwupdManager.get_instance ().install (device.id, device.latest_release); - on_updated (); + update_button.sensitive = false; + + FwupdManager.get_instance ().install.begin (device.id, device.latest_release, (obj, res) => { + FwupdManager.get_instance ().install.end (res); + on_updated (); + }); }); grid.attach (update_button, 2, 0, 1, 2); break; From 96bed5dcfe2fb3caa494aca13baf52a120ab7205 Mon Sep 17 00:00:00 2001 From: Marius Meisenzahl Date: Tue, 29 Dec 2020 15:32:38 +0100 Subject: [PATCH 35/96] Refactor handle --- src/Interfaces/FwupdManager.vala | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/Interfaces/FwupdManager.vala b/src/Interfaces/FwupdManager.vala index f5220d8eb..98eb69335 100644 --- a/src/Interfaces/FwupdManager.vala +++ b/src/Interfaces/FwupdManager.vala @@ -222,9 +222,11 @@ public class About.FwupdManager : Object { return Path.build_path (Path.DIR_SEPARATOR_S, Environment.get_tmp_dir (), file_path); } - private UnixInputStream get_handle (string path) { + private int get_handle (string path) throws Error { var fd = ro_fd (path); - return new UnixInputStream (fd, true); + var fd_list = new UnixFDList (); + var stream = new UnixInputStream (fd, true); + return fd_list.append (stream.fd); } public async void install (string id, Release release) { @@ -249,7 +251,13 @@ public class About.FwupdManager : Object { return; } - var handle = get_handle (path); + int handle; + try { + handle = get_handle (path); + } catch (Error e) { + warning ("Could not get handle: %s", e.message); + return; + } // https://github.com/fwupd/fwupd/blob/c0d4c09a02a40167e9de57f82c0033bb92e24167/libfwupd/fwupd-client.c#L2045 var options = new VariantBuilder (new VariantType ("a{sv}")); @@ -265,7 +273,7 @@ public class About.FwupdManager : Object { var parameters = new VariantBuilder (new VariantType ("(sha{sv})")); parameters.add_value (new Variant.string (id)); - parameters.add_value (new Variant.handle (handle.fd)); + parameters.add_value (new Variant.handle (handle)); parameters.add_value (options.end ()); try { From e08d741bcb251cbfaeaead0efee8acd5826b7122 Mon Sep 17 00:00:00 2001 From: Marius Meisenzahl Date: Tue, 29 Dec 2020 15:55:14 +0100 Subject: [PATCH 36/96] Refactor handle --- src/Interfaces/FwupdManager.vala | 49 +++++++++++++------------------- 1 file changed, 20 insertions(+), 29 deletions(-) diff --git a/src/Interfaces/FwupdManager.vala b/src/Interfaces/FwupdManager.vala index 98eb69335..1f4fd8c16 100644 --- a/src/Interfaces/FwupdManager.vala +++ b/src/Interfaces/FwupdManager.vala @@ -222,13 +222,6 @@ public class About.FwupdManager : Object { return Path.build_path (Path.DIR_SEPARATOR_S, Environment.get_tmp_dir (), file_path); } - private int get_handle (string path) throws Error { - var fd = ro_fd (path); - var fd_list = new UnixFDList (); - var stream = new UnixInputStream (fd, true); - return fd_list.append (stream.fd); - } - public async void install (string id, Release release) { var path = get_path (release); @@ -251,32 +244,30 @@ public class About.FwupdManager : Object { return; } - int handle; try { - handle = get_handle (path); - } catch (Error e) { - warning ("Could not get handle: %s", e.message); - return; - } + // https://github.com/fwupd/fwupd/blob/c0d4c09a02a40167e9de57f82c0033bb92e24167/libfwupd/fwupd-client.c#L2045 + var options = new VariantBuilder (new VariantType ("a{sv}")); + options.add ("{sv}", "reason", new Variant.string ("user-action")); + options.add ("{sv}", "filename", new Variant.string (path)); + // options.add ("{sv}", "offline", new Variant.boolean (true)); + options.add ("{sv}", "allow-older", new Variant.boolean (true)); + options.add ("{sv}", "allow-reinstall", new Variant.boolean (true)); + // options.add ("{sv}", "allow-branch-switch", new Variant.boolean (true)); + // options.add ("{sv}", "force", new Variant.boolean (true)); + // options.add ("{sv}", "ignore-power", new Variant.boolean (true)); + options.add ("{sv}", "no-history", new Variant.boolean (true)); - // https://github.com/fwupd/fwupd/blob/c0d4c09a02a40167e9de57f82c0033bb92e24167/libfwupd/fwupd-client.c#L2045 - var options = new VariantBuilder (new VariantType ("a{sv}")); - options.add ("{sv}", "reason", new Variant.string ("user-action")); - options.add ("{sv}", "filename", new Variant.string (path)); - // options.add ("{sv}", "offline", new Variant.boolean (true)); - options.add ("{sv}", "allow-older", new Variant.boolean (true)); - options.add ("{sv}", "allow-reinstall", new Variant.boolean (true)); - // options.add ("{sv}", "allow-branch-switch", new Variant.boolean (true)); - // options.add ("{sv}", "force", new Variant.boolean (true)); - // options.add ("{sv}", "ignore-power", new Variant.boolean (true)); - options.add ("{sv}", "no-history", new Variant.boolean (true)); + var parameters = new VariantBuilder (new VariantType ("(sha{sv})")); + parameters.add_value (new Variant.string (id)); - var parameters = new VariantBuilder (new VariantType ("(sha{sv})")); - parameters.add_value (new Variant.string (id)); - parameters.add_value (new Variant.handle (handle)); - parameters.add_value (options.end ()); + var fd = ro_fd (path); + var fd_list = new UnixFDList (); + var stream = new UnixInputStream (fd, true); + var handle = fd_list.append (stream.fd); + parameters.add_value (new Variant.handle (handle)); + + parameters.add_value (options.end ()); - try { yield connection.call ( "org.freedesktop.fwupd", "/", From ef6a622ab3915839e8c9878b06fb75253e935655 Mon Sep 17 00:00:00 2001 From: Marius Meisenzahl Date: Wed, 30 Dec 2020 07:07:46 +0100 Subject: [PATCH 37/96] Refactor handle --- src/Interfaces/FwupdManager.vala | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/Interfaces/FwupdManager.vala b/src/Interfaces/FwupdManager.vala index 1f4fd8c16..60f3a4ec0 100644 --- a/src/Interfaces/FwupdManager.vala +++ b/src/Interfaces/FwupdManager.vala @@ -263,12 +263,12 @@ public class About.FwupdManager : Object { var fd = ro_fd (path); var fd_list = new UnixFDList (); var stream = new UnixInputStream (fd, true); - var handle = fd_list.append (stream.fd); - parameters.add_value (new Variant.handle (handle)); + fd_list.append (stream.fd); + parameters.add_value (new Variant.handle (0)); parameters.add_value (options.end ()); - yield connection.call ( + yield connection.call_with_unix_fd_list ( "org.freedesktop.fwupd", "/", "org.freedesktop.fwupd", @@ -276,7 +276,8 @@ public class About.FwupdManager : Object { parameters.end (), null, DBusCallFlags.NONE, - -1 + -1, + fd_list ); } catch (Error e) { warning ("Could not connect to fwupd interface: %s", e.message); From cfd904ffc8e8c79f7bf271985757f41a9b3de5ee Mon Sep 17 00:00:00 2001 From: Marius Meisenzahl Date: Sun, 3 Jan 2021 04:59:24 +0100 Subject: [PATCH 38/96] Show feedback during update --- src/Views/FirmwareView.vala | 32 ++++++++++++++++++++++++--- src/Widgets/FirmwareUpdateWidget.vala | 7 +++--- 2 files changed, 33 insertions(+), 6 deletions(-) diff --git a/src/Views/FirmwareView.vala b/src/Views/FirmwareView.vala index 45cada5b5..c79e003b7 100644 --- a/src/Views/FirmwareView.vala +++ b/src/Views/FirmwareView.vala @@ -21,6 +21,9 @@ public class About.FirmwareView : Granite.SettingsPage { private Gtk.Button update_all_button; + private Gtk.Stack stack; + private Gtk.Frame frame; + private Gtk.Grid progress_view; private Gtk.ListBox update_list; public FirmwareView () { @@ -31,6 +34,17 @@ public class About.FirmwareView : Granite.SettingsPage { } construct { + var progress_alert_view = new Granite.Widgets.AlertView ( + _("Device is being updated"), + _("Do not unplug the device during the update."), + "emblem-synchronized" + ); + progress_alert_view.get_style_context ().remove_class (Gtk.STYLE_CLASS_VIEW); + + progress_view = new Gtk.Grid (); + progress_view.margin = 24; + progress_view.attach (progress_alert_view, 0, 0, 1, 1); + var header_icon = new Gtk.Image.from_icon_name ("application-x-firmware", Gtk.IconSize.DIALOG) { pixel_size = 48, valign = Gtk.Align.START @@ -64,13 +78,19 @@ public class About.FirmwareView : Granite.SettingsPage { var scrolled_window = new Gtk.ScrolledWindow (null, null); scrolled_window.add (update_list); - var frame = new Gtk.Frame (null); + frame = new Gtk.Frame (null); frame.add (scrolled_window); + stack = new Gtk.Stack (); + stack.transition_type = Gtk.StackTransitionType.SLIDE_LEFT_RIGHT; + + stack.add (frame); + stack.add (progress_view); + grid.attach (header_icon, 0, 0); grid.attach (title_label, 1, 0); grid.attach (update_all_button, 2, 0); - grid.attach (frame, 0, 1, 3, 1); + grid.attach (stack, 0, 1, 3, 1); add (grid); @@ -89,7 +109,13 @@ public class About.FirmwareView : Granite.SettingsPage { var widget = new Widgets.FirmwareUpdateWidget (device); update_list.add (widget); - widget.on_updated.connect (update_list_view); + widget.on_update_start.connect (() => { + stack.visible_child = progress_view; + }); + widget.on_update_end.connect (() => { + stack.visible_child = frame; + update_list_view.begin (); + }); } } diff --git a/src/Widgets/FirmwareUpdateWidget.vala b/src/Widgets/FirmwareUpdateWidget.vala index 6e4732e14..f1d38422c 100644 --- a/src/Widgets/FirmwareUpdateWidget.vala +++ b/src/Widgets/FirmwareUpdateWidget.vala @@ -22,7 +22,8 @@ public class About.Widgets.FirmwareUpdateWidget : Gtk.ListBoxRow { public Device device { get; construct set; } - public signal void on_updated (); + public signal void on_update_start (); + public signal void on_update_end (); public FirmwareUpdateWidget (Device device) { GLib.Object ( @@ -64,11 +65,11 @@ public class About.Widgets.FirmwareUpdateWidget : Gtk.ListBoxRow { valign = Gtk.Align.CENTER }; update_button.clicked.connect (() => { - update_button.sensitive = false; + on_update_start (); FwupdManager.get_instance ().install.begin (device.id, device.latest_release, (obj, res) => { FwupdManager.get_instance ().install.end (res); - on_updated (); + on_update_end (); }); }); grid.attach (update_button, 2, 0, 1, 2); From da2620c0a2c940c9355966b4bd3d5887c8bf1265 Mon Sep 17 00:00:00 2001 From: Marius Meisenzahl Date: Sun, 3 Jan 2021 05:01:48 +0100 Subject: [PATCH 39/96] Remove dummy update all button --- src/Views/FirmwareView.vala | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/src/Views/FirmwareView.vala b/src/Views/FirmwareView.vala index c79e003b7..76157b682 100644 --- a/src/Views/FirmwareView.vala +++ b/src/Views/FirmwareView.vala @@ -20,7 +20,6 @@ */ public class About.FirmwareView : Granite.SettingsPage { - private Gtk.Button update_all_button; private Gtk.Stack stack; private Gtk.Frame frame; private Gtk.Grid progress_view; @@ -52,18 +51,12 @@ public class About.FirmwareView : Granite.SettingsPage { var title_label = new Gtk.Label (_("Firmware")) { ellipsize = Pango.EllipsizeMode.END, + hexpand = true, selectable = true, xalign = 0 }; title_label.get_style_context ().add_class (Granite.STYLE_CLASS_H2_LABEL); - update_all_button = new Gtk.Button.with_label (_("Update All")) { - hexpand = true, - halign = Gtk.Align.END, - valign = Gtk.Align.CENTER, - sensitive = false - }; - var grid = new Gtk.Grid () { column_spacing = 12, row_spacing = 12, @@ -89,7 +82,6 @@ public class About.FirmwareView : Granite.SettingsPage { grid.attach (header_icon, 0, 0); grid.attach (title_label, 1, 0); - grid.attach (update_all_button, 2, 0); grid.attach (stack, 0, 1, 3, 1); add (grid); From 2d1fbdc241f51caf53b061e651997d4ae98160f9 Mon Sep 17 00:00:00 2001 From: Marius Meisenzahl Date: Sun, 3 Jan 2021 05:09:44 +0100 Subject: [PATCH 40/96] Update layout --- src/Views/FirmwareView.vala | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/Views/FirmwareView.vala b/src/Views/FirmwareView.vala index 76157b682..736bfb5ca 100644 --- a/src/Views/FirmwareView.vala +++ b/src/Views/FirmwareView.vala @@ -21,7 +21,7 @@ public class About.FirmwareView : Granite.SettingsPage { private Gtk.Stack stack; - private Gtk.Frame frame; + private Gtk.Grid grid; private Gtk.Grid progress_view; private Gtk.ListBox update_list; @@ -57,7 +57,7 @@ public class About.FirmwareView : Granite.SettingsPage { }; title_label.get_style_context ().add_class (Granite.STYLE_CLASS_H2_LABEL); - var grid = new Gtk.Grid () { + grid = new Gtk.Grid () { column_spacing = 12, row_spacing = 12, margin = 12 @@ -71,20 +71,20 @@ public class About.FirmwareView : Granite.SettingsPage { var scrolled_window = new Gtk.ScrolledWindow (null, null); scrolled_window.add (update_list); - frame = new Gtk.Frame (null); + var frame = new Gtk.Frame (null); frame.add (scrolled_window); + grid.attach (header_icon, 0, 0); + grid.attach (title_label, 1, 0); + grid.attach (frame, 0, 1, 3, 1); + stack = new Gtk.Stack (); stack.transition_type = Gtk.StackTransitionType.SLIDE_LEFT_RIGHT; - stack.add (frame); + stack.add (grid); stack.add (progress_view); - grid.attach (header_icon, 0, 0); - grid.attach (title_label, 1, 0); - grid.attach (stack, 0, 1, 3, 1); - - add (grid); + add (stack); update_list_view.begin (); } @@ -105,7 +105,7 @@ public class About.FirmwareView : Granite.SettingsPage { stack.visible_child = progress_view; }); widget.on_update_end.connect (() => { - stack.visible_child = frame; + stack.visible_child = grid; update_list_view.begin (); }); } From 8cc66777bae35fec9cefaa28f63ae1bc441256e4 Mon Sep 17 00:00:00 2001 From: Marius Meisenzahl Date: Sun, 3 Jan 2021 05:22:31 +0100 Subject: [PATCH 41/96] Refactor --- src/Views/FirmwareView.vala | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Views/FirmwareView.vala b/src/Views/FirmwareView.vala index 736bfb5ca..4397046c2 100644 --- a/src/Views/FirmwareView.vala +++ b/src/Views/FirmwareView.vala @@ -40,8 +40,9 @@ public class About.FirmwareView : Granite.SettingsPage { ); progress_alert_view.get_style_context ().remove_class (Gtk.STYLE_CLASS_VIEW); - progress_view = new Gtk.Grid (); - progress_view.margin = 24; + progress_view = new Gtk.Grid () { + margin = 24 + }; progress_view.attach (progress_alert_view, 0, 0, 1, 1); var header_icon = new Gtk.Image.from_icon_name ("application-x-firmware", Gtk.IconSize.DIALOG) { From b068d38bd00147bbffebfcf8bb377b4e11bc9bd8 Mon Sep 17 00:00:00 2001 From: Marius Meisenzahl Date: Wed, 13 Jan 2021 19:05:31 +0100 Subject: [PATCH 42/96] Remove unused code --- src/Interfaces/FwupdManager.vala | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/Interfaces/FwupdManager.vala b/src/Interfaces/FwupdManager.vala index 60f3a4ec0..f946a9fd5 100644 --- a/src/Interfaces/FwupdManager.vala +++ b/src/Interfaces/FwupdManager.vala @@ -249,12 +249,8 @@ public class About.FwupdManager : Object { var options = new VariantBuilder (new VariantType ("a{sv}")); options.add ("{sv}", "reason", new Variant.string ("user-action")); options.add ("{sv}", "filename", new Variant.string (path)); - // options.add ("{sv}", "offline", new Variant.boolean (true)); options.add ("{sv}", "allow-older", new Variant.boolean (true)); options.add ("{sv}", "allow-reinstall", new Variant.boolean (true)); - // options.add ("{sv}", "allow-branch-switch", new Variant.boolean (true)); - // options.add ("{sv}", "force", new Variant.boolean (true)); - // options.add ("{sv}", "ignore-power", new Variant.boolean (true)); options.add ("{sv}", "no-history", new Variant.boolean (true)); var parameters = new VariantBuilder (new VariantType ("(sha{sv})")); From 25a3ea8ec9353f4417ec838ed6762642ddc345fa Mon Sep 17 00:00:00 2001 From: Marius Meisenzahl Date: Wed, 13 Jan 2021 19:06:22 +0100 Subject: [PATCH 43/96] Update src/Interfaces/FwupdManager.vala MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Daniel Foré --- src/Interfaces/FwupdManager.vala | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Interfaces/FwupdManager.vala b/src/Interfaces/FwupdManager.vala index f946a9fd5..848a2662b 100644 --- a/src/Interfaces/FwupdManager.vala +++ b/src/Interfaces/FwupdManager.vala @@ -253,15 +253,15 @@ public class About.FwupdManager : Object { options.add ("{sv}", "allow-reinstall", new Variant.boolean (true)); options.add ("{sv}", "no-history", new Variant.boolean (true)); - var parameters = new VariantBuilder (new VariantType ("(sha{sv})")); - parameters.add_value (new Variant.string (id)); - var fd = ro_fd (path); - var fd_list = new UnixFDList (); var stream = new UnixInputStream (fd, true); + + var fd_list = new UnixFDList (); fd_list.append (stream.fd); + + var parameters = new VariantBuilder (new VariantType ("(sha{sv})")); + parameters.add_value (new Variant.string (id)); parameters.add_value (new Variant.handle (0)); - parameters.add_value (options.end ()); yield connection.call_with_unix_fd_list ( From ed5e1f5f76356936b24d9ba8fbc8a61a7d88e610 Mon Sep 17 00:00:00 2001 From: Marius Meisenzahl Date: Wed, 13 Jan 2021 19:06:39 +0100 Subject: [PATCH 44/96] Update src/Plug.vala MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Daniel Foré --- src/Plug.vala | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/Plug.vala b/src/Plug.vala index 476d58653..c65a71dc7 100644 --- a/src/Plug.vala +++ b/src/Plug.vala @@ -46,11 +46,12 @@ public class About.Plug : Switchboard.Plug { var firmware_view = new FirmwareView (); stack.add_titled (firmware_view, "firmware", _("Firmware")); - var stack_switcher = new Gtk.StackSwitcher (); - stack_switcher.stack = stack; - stack_switcher.halign = Gtk.Align.CENTER; - stack_switcher.homogeneous = true; - stack_switcher.margin = 24; + var stack_switcher = new Gtk.StackSwitcher () { + halign = Gtk.Align.CENTER, + homogeneous = true, + margin = 24, + stack = stack + }; main_grid.attach (stack_switcher, 0, 0, 1, 1); main_grid.attach (stack, 0, 1, 1, 1); From 30399a763be9d1f04d409db51eb77f21f3994e6a Mon Sep 17 00:00:00 2001 From: Marius Meisenzahl Date: Wed, 13 Jan 2021 19:07:01 +0100 Subject: [PATCH 45/96] Update src/Plug.vala MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Daniel Foré --- src/Plug.vala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Plug.vala b/src/Plug.vala index c65a71dc7..203976103 100644 --- a/src/Plug.vala +++ b/src/Plug.vala @@ -53,8 +53,8 @@ public class About.Plug : Switchboard.Plug { stack = stack }; - main_grid.attach (stack_switcher, 0, 0, 1, 1); - main_grid.attach (stack, 0, 1, 1, 1); + main_grid.attach (stack_switcher, 0, 0); + main_grid.attach (stack, 0, 1); main_grid.show_all (); } From f7bb77fa1d0f4a4eda793b69ab34f0e9926a2a87 Mon Sep 17 00:00:00 2001 From: Marius Meisenzahl Date: Wed, 13 Jan 2021 19:07:34 +0100 Subject: [PATCH 46/96] Update src/Views/FirmwareView.vala MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Daniel Foré --- src/Views/FirmwareView.vala | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/Views/FirmwareView.vala b/src/Views/FirmwareView.vala index 4397046c2..96c85b694 100644 --- a/src/Views/FirmwareView.vala +++ b/src/Views/FirmwareView.vala @@ -58,12 +58,6 @@ public class About.FirmwareView : Granite.SettingsPage { }; title_label.get_style_context ().add_class (Granite.STYLE_CLASS_H2_LABEL); - grid = new Gtk.Grid () { - column_spacing = 12, - row_spacing = 12, - margin = 12 - }; - update_list = new Gtk.ListBox () { vexpand = true, selection_mode = Gtk.SelectionMode.SINGLE @@ -75,6 +69,11 @@ public class About.FirmwareView : Granite.SettingsPage { var frame = new Gtk.Frame (null); frame.add (scrolled_window); + grid = new Gtk.Grid () { + column_spacing = 12, + row_spacing = 12, + margin = 12 + }; grid.attach (header_icon, 0, 0); grid.attach (title_label, 1, 0); grid.attach (frame, 0, 1, 3, 1); From cbdb26a003baae41febd65eff9cc55c1ca097f4c Mon Sep 17 00:00:00 2001 From: Marius Meisenzahl Date: Wed, 13 Jan 2021 19:09:32 +0100 Subject: [PATCH 47/96] Refactor reference type --- src/Views/FirmwareView.vala | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Views/FirmwareView.vala b/src/Views/FirmwareView.vala index 96c85b694..886c2faaa 100644 --- a/src/Views/FirmwareView.vala +++ b/src/Views/FirmwareView.vala @@ -90,9 +90,9 @@ public class About.FirmwareView : Granite.SettingsPage { } private async void update_list_view () { - foreach (Gtk.Widget element in update_list.get_children ()) { - if (element is Gtk.ListBoxRow) { - update_list.remove (element); + foreach (unowned Gtk.Widget widget in update_list.get_children ()) { + if (widget is Gtk.ListBoxRow) { + update_list.remove (widget); } } From bfee445d450c92f755bad9b04715c39690cf72ae Mon Sep 17 00:00:00 2001 From: Marius Meisenzahl Date: Wed, 13 Jan 2021 19:11:40 +0100 Subject: [PATCH 48/96] Update src/Widgets/FirmwareUpdateWidget.vala MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Daniel Foré --- src/Widgets/FirmwareUpdateWidget.vala | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/Widgets/FirmwareUpdateWidget.vala b/src/Widgets/FirmwareUpdateWidget.vala index f1d38422c..db7170ff4 100644 --- a/src/Widgets/FirmwareUpdateWidget.vala +++ b/src/Widgets/FirmwareUpdateWidget.vala @@ -26,9 +26,7 @@ public class About.Widgets.FirmwareUpdateWidget : Gtk.ListBoxRow { public signal void on_update_end (); public FirmwareUpdateWidget (Device device) { - GLib.Object ( - device: device - ); + Object (device: device); } construct { From 3d7ba6bcccac080c697426894b437417c4f8bb2c Mon Sep 17 00:00:00 2001 From: Marius Meisenzahl Date: Wed, 13 Jan 2021 19:11:50 +0100 Subject: [PATCH 49/96] Update src/Widgets/FirmwareUpdateWidget.vala MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Daniel Foré --- src/Widgets/FirmwareUpdateWidget.vala | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/Widgets/FirmwareUpdateWidget.vala b/src/Widgets/FirmwareUpdateWidget.vala index db7170ff4..552b5888e 100644 --- a/src/Widgets/FirmwareUpdateWidget.vala +++ b/src/Widgets/FirmwareUpdateWidget.vala @@ -45,9 +45,10 @@ public class About.Widgets.FirmwareUpdateWidget : Gtk.ListBoxRow { xalign = 0 }; - var grid = new Gtk.Grid (); - grid.column_spacing = 12; - grid.margin = 6; + var grid = new Gtk.Grid () { + column_spacing = 12, + margin = 6 + }; grid.attach (icon, 0, 0, 1, 2); grid.attach (device_name_label, 1, 0); grid.attach (version_label, 1, 1); From a9ccd73cdc459c3cec0a4bfa0e7c604e0314676e Mon Sep 17 00:00:00 2001 From: Marius Meisenzahl Date: Wed, 13 Jan 2021 19:40:30 +0100 Subject: [PATCH 50/96] Show placeholder when no devices are available --- src/Views/FirmwareView.vala | 48 ++++++++++++++++++++++++++++--------- 1 file changed, 37 insertions(+), 11 deletions(-) diff --git a/src/Views/FirmwareView.vala b/src/Views/FirmwareView.vala index 886c2faaa..812e53d5b 100644 --- a/src/Views/FirmwareView.vala +++ b/src/Views/FirmwareView.vala @@ -23,6 +23,7 @@ public class About.FirmwareView : Granite.SettingsPage { private Gtk.Stack stack; private Gtk.Grid grid; private Gtk.Grid progress_view; + private Gtk.Grid no_devices_view; private Gtk.ListBox update_list; public FirmwareView () { @@ -43,7 +44,19 @@ public class About.FirmwareView : Granite.SettingsPage { progress_view = new Gtk.Grid () { margin = 24 }; - progress_view.attach (progress_alert_view, 0, 0, 1, 1); + progress_view.attach (progress_alert_view, 0, 0); + + var no_devices_alert_view = new Granite.Widgets.AlertView ( + _("No devices available"), + _("We're unable to provide updates for device firmware."), + "application-x-firmware" + ); + no_devices_alert_view.get_style_context ().remove_class (Gtk.STYLE_CLASS_VIEW); + + no_devices_view = new Gtk.Grid () { + margin = 24 + }; + no_devices_view.attach (no_devices_alert_view, 0, 0); var header_icon = new Gtk.Image.from_icon_name ("application-x-firmware", Gtk.IconSize.DIALOG) { pixel_size = 48, @@ -83,6 +96,7 @@ public class About.FirmwareView : Granite.SettingsPage { stack.add (grid); stack.add (progress_view); + stack.add (no_devices_view); add (stack); @@ -96,21 +110,33 @@ public class About.FirmwareView : Granite.SettingsPage { } } + List devices = new List (); foreach (var device in yield FwupdManager.get_instance ().get_devices ()) { if (device.is (DeviceFlag.UPDATABLE) && device.releases.length () > 0) { - var widget = new Widgets.FirmwareUpdateWidget (device); - update_list.add (widget); - - widget.on_update_start.connect (() => { - stack.visible_child = progress_view; - }); - widget.on_update_end.connect (() => { - stack.visible_child = grid; - update_list_view.begin (); - }); + devices.append (device); } } + if (devices.length () == 0) { + stack.visible_child = no_devices_view; + return; + } else { + stack.visible_child = grid; + } + + foreach (var device in devices) { + var widget = new Widgets.FirmwareUpdateWidget (device); + update_list.add (widget); + + widget.on_update_start.connect (() => { + stack.visible_child = progress_view; + }); + widget.on_update_end.connect (() => { + stack.visible_child = grid; + update_list_view.begin (); + }); + } + update_list.show_all (); } } From 1671569b47378a1f95cbca973d3e4b0264748080 Mon Sep 17 00:00:00 2001 From: Marius Meisenzahl Date: Wed, 13 Jan 2021 20:11:01 +0100 Subject: [PATCH 51/96] Show error dialog --- src/Interfaces/FwupdManager.vala | 11 +++++++---- src/Views/FirmwareView.vala | 15 +++++++++++++++ src/Widgets/FirmwareUpdateWidget.vala | 2 +- 3 files changed, 23 insertions(+), 5 deletions(-) diff --git a/src/Interfaces/FwupdManager.vala b/src/Interfaces/FwupdManager.vala index 3a263cf12..3e91e19ea 100644 --- a/src/Interfaces/FwupdManager.vala +++ b/src/Interfaces/FwupdManager.vala @@ -26,6 +26,8 @@ public class About.FwupdManager : Object { public signal void changed (); + public signal void on_error (string error); + static FwupdManager? instance = null; public static FwupdManager get_instance () { if (instance == null) { @@ -222,7 +224,7 @@ public class About.FwupdManager : Object { return Path.build_path (Path.DIR_SEPARATOR_S, Environment.get_tmp_dir (), file_path); } - public async void install (string id, Release release) { + public async void install (Device device, Release release) { var path = get_path (release); File server_file = File.new_for_uri (release.uri); @@ -235,12 +237,12 @@ public class About.FwupdManager : Object { current_num_bytes, release.size); }); } catch (Error e) { - warning ("Could not download file: %s", e.message); + on_error ("Could not download file: %s".printf (e.message)); return; } if (!result) { - warning ("Download of %s was not succesfull", release.uri); + on_error ("Download of %s was not succesfull".printf (release.uri)); return; } @@ -260,7 +262,7 @@ public class About.FwupdManager : Object { fd_list.append (stream.fd); var parameters = new VariantBuilder (new VariantType ("(sha{sv})")); - parameters.add_value (new Variant.string (id)); + parameters.add_value (new Variant.string (device.id)); parameters.add_value (new Variant.handle (0)); parameters.add_value (options.end ()); @@ -277,6 +279,7 @@ public class About.FwupdManager : Object { ); } catch (Error e) { warning ("Could not connect to fwupd interface: %s", e.message); + on_error (device.update_error); } } diff --git a/src/Views/FirmwareView.vala b/src/Views/FirmwareView.vala index 812e53d5b..c5737c4be 100644 --- a/src/Views/FirmwareView.vala +++ b/src/Views/FirmwareView.vala @@ -100,6 +100,8 @@ public class About.FirmwareView : Granite.SettingsPage { add (stack); + FwupdManager.get_instance ().on_error.connect (on_error); + update_list_view.begin (); } @@ -139,4 +141,17 @@ public class About.FirmwareView : Granite.SettingsPage { update_list.show_all (); } + + private void on_error (string error) { + var message_dialog = new Granite.MessageDialog.with_image_from_icon_name ( + _("Failed to install firmware release"), + error, + "application-x-firmware", + Gtk.ButtonsType.CLOSE + ); + message_dialog.badge_icon = new ThemedIcon ("dialog-error"); + message_dialog.show_all (); + message_dialog.run (); + message_dialog.destroy (); + } } diff --git a/src/Widgets/FirmwareUpdateWidget.vala b/src/Widgets/FirmwareUpdateWidget.vala index 552b5888e..fcc771dc3 100644 --- a/src/Widgets/FirmwareUpdateWidget.vala +++ b/src/Widgets/FirmwareUpdateWidget.vala @@ -66,7 +66,7 @@ public class About.Widgets.FirmwareUpdateWidget : Gtk.ListBoxRow { update_button.clicked.connect (() => { on_update_start (); - FwupdManager.get_instance ().install.begin (device.id, device.latest_release, (obj, res) => { + FwupdManager.get_instance ().install.begin (device, device.latest_release, (obj, res) => { FwupdManager.get_instance ().install.end (res); on_update_end (); }); From 34f936dd449c084d34f1b1a6cf1113a91d8a5175 Mon Sep 17 00:00:00 2001 From: Marius Meisenzahl Date: Wed, 13 Jan 2021 20:27:35 +0100 Subject: [PATCH 52/96] Update src/Views/FirmwareView.vala Co-authored-by: Cassidy James Blaede --- src/Views/FirmwareView.vala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Views/FirmwareView.vala b/src/Views/FirmwareView.vala index c5737c4be..254dbae04 100644 --- a/src/Views/FirmwareView.vala +++ b/src/Views/FirmwareView.vala @@ -47,8 +47,8 @@ public class About.FirmwareView : Granite.SettingsPage { progress_view.attach (progress_alert_view, 0, 0); var no_devices_alert_view = new Granite.Widgets.AlertView ( - _("No devices available"), - _("We're unable to provide updates for device firmware."), + _("No updatable devices"), + _("Firmware updates are not supported on this or any connected devices."), "application-x-firmware" ); no_devices_alert_view.get_style_context ().remove_class (Gtk.STYLE_CLASS_VIEW); From 162b2723ee94572a864cb99e3cbfe1b73024cad9 Mon Sep 17 00:00:00 2001 From: Marius Meisenzahl Date: Thu, 14 Jan 2021 20:53:56 +0100 Subject: [PATCH 53/96] Add GetDetails --- src/Interfaces/FwupdManager.vala | 76 ++++++++++++++++++++++++++++++++ src/Objects/Details.vala | 25 +++++++++++ src/meson.build | 1 + 3 files changed, 102 insertions(+) create mode 100644 src/Objects/Details.vala diff --git a/src/Interfaces/FwupdManager.vala b/src/Interfaces/FwupdManager.vala index 3e91e19ea..99b3cdda6 100644 --- a/src/Interfaces/FwupdManager.vala +++ b/src/Interfaces/FwupdManager.vala @@ -283,6 +283,82 @@ public class About.FwupdManager : Object { } } + public async Details get_details (Device device, Release release) { + var details = new Details (); + + var path = get_path (release); + + File server_file = File.new_for_uri (release.uri); + File local_file = File.new_for_path (path); + + bool result; + try { + result = yield server_file.copy_async (local_file, FileCopyFlags.OVERWRITE, Priority.DEFAULT, null, (current_num_bytes, total_num_bytes) => { + debug ("%" + int64.FORMAT + " bytes of %" + int64.FORMAT + " bytes copied.", + current_num_bytes, release.size); + }); + } catch (Error e) { + on_error ("Could not download file: %s".printf (e.message)); + return details; + } + + if (!result) { + on_error ("Download of %s was not succesfull".printf (release.uri)); + return details; + } + + try { + var fd = ro_fd (path); + var stream = new UnixInputStream (fd, true); + + var fd_list = new UnixFDList (); + fd_list.append (stream.fd); + + var parameters = new VariantBuilder (new VariantType ("(h)")); + parameters.add_value (new Variant.handle (0)); + + var r = yield connection.call_with_unix_fd_list ( + "org.freedesktop.fwupd", + "/", + "org.freedesktop.fwupd", + "GetDetails", + parameters.end (), + new VariantType ("(aa{sv})"), + DBusCallFlags.NONE, + -1, + fd_list + ); + + var array_iter = r.iterator (); + GLib.Variant? element = array_iter.next_value (); + array_iter = element.iterator (); + + while ((element = array_iter.next_value ()) != null) { + GLib.Variant? val = null; + string? key = null; + + var details_iter = element.iterator (); + while (details_iter.next ("{sv}", out key, out val)) { + if (key == "Release") { + var release_iter = val.iterator ().next_value ().iterator (); + while (release_iter.next ("{sv}", out key, out val)) { + if (key == "DetachCaption") { + details.caption = val.get_string (); + } else if (key == "DetachImage") { + details.image = val.get_string (); + } + } + } + } + } + } catch (Error e) { + warning ("Could not connect to fwupd interface: %s", e.message); + on_error (device.update_error); + } + + return details; + } + construct { try { connection = Bus.get_sync (BusType.SYSTEM); diff --git a/src/Objects/Details.vala b/src/Objects/Details.vala new file mode 100644 index 000000000..7d80a833a --- /dev/null +++ b/src/Objects/Details.vala @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2021 elementary, Inc. (https://elementary.io) + * + * 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 3 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 + * + * Authored by: Marius Meisenzahl + */ + +public class About.Details : Object { + public string caption { get; set; } + public string image { get; set; } +} diff --git a/src/meson.build b/src/meson.build index 1022a7760..873607681 100644 --- a/src/meson.build +++ b/src/meson.build @@ -1,6 +1,7 @@ plug_files = files( 'fd.c', 'Plug.vala', + 'Objects/Details.vala', 'Objects/Device.vala', 'Objects/DeviceFlag.vala', 'Objects/Release.vala', From fde76d6579c7a6bc2421a43e65da09ce4ad3d44f Mon Sep 17 00:00:00 2001 From: Marius Meisenzahl Date: Thu, 14 Jan 2021 21:33:53 +0100 Subject: [PATCH 54/96] Show dialog if manual steps are required --- src/Interfaces/FwupdManager.vala | 56 +++++++++++---------------- src/Widgets/FirmwareUpdateWidget.vala | 39 ++++++++++++++++++- 2 files changed, 59 insertions(+), 36 deletions(-) diff --git a/src/Interfaces/FwupdManager.vala b/src/Interfaces/FwupdManager.vala index 99b3cdda6..b94950bfe 100644 --- a/src/Interfaces/FwupdManager.vala +++ b/src/Interfaces/FwupdManager.vala @@ -218,34 +218,39 @@ public class About.FwupdManager : Object { return releases_list; } - private string get_path (Release release) { - var parts = release.uri.split ("/"); + private string get_path (string uri) { + var parts = uri.split ("/"); string file_path = parts[parts.length - 1]; return Path.build_path (Path.DIR_SEPARATOR_S, Environment.get_tmp_dir (), file_path); } - public async void install (Device device, Release release) { - var path = get_path (release); + public async string? download_file (string uri) { + var path = get_path (uri); - File server_file = File.new_for_uri (release.uri); + File server_file = File.new_for_uri (uri); File local_file = File.new_for_path (path); + if (FileUtils.test (path, FileTest.IS_REGULAR)) { + return path; + } + bool result; try { - result = yield server_file.copy_async (local_file, FileCopyFlags.OVERWRITE, Priority.DEFAULT, null, (current_num_bytes, total_num_bytes) => { - debug ("%" + int64.FORMAT + " bytes of %" + int64.FORMAT + " bytes copied.", - current_num_bytes, release.size); - }); + result = yield server_file.copy_async (local_file, FileCopyFlags.OVERWRITE, Priority.DEFAULT, null, (current_num_bytes, total_num_bytes) => {}); } catch (Error e) { on_error ("Could not download file: %s".printf (e.message)); - return; + return null; } if (!result) { - on_error ("Download of %s was not succesfull".printf (release.uri)); - return; + on_error ("Download of %s was not succesfull".printf (uri)); + return null; } + return path; + } + + public async void install (Device device, string path) { try { // https://github.com/fwupd/fwupd/blob/c0d4c09a02a40167e9de57f82c0033bb92e24167/libfwupd/fwupd-client.c#L2045 var options = new VariantBuilder (new VariantType ("a{sv}")); @@ -283,30 +288,9 @@ public class About.FwupdManager : Object { } } - public async Details get_details (Device device, Release release) { + public async Details get_details (Device device, string path) { var details = new Details (); - var path = get_path (release); - - File server_file = File.new_for_uri (release.uri); - File local_file = File.new_for_path (path); - - bool result; - try { - result = yield server_file.copy_async (local_file, FileCopyFlags.OVERWRITE, Priority.DEFAULT, null, (current_num_bytes, total_num_bytes) => { - debug ("%" + int64.FORMAT + " bytes of %" + int64.FORMAT + " bytes copied.", - current_num_bytes, release.size); - }); - } catch (Error e) { - on_error ("Could not download file: %s".printf (e.message)); - return details; - } - - if (!result) { - on_error ("Download of %s was not succesfull".printf (release.uri)); - return details; - } - try { var fd = ro_fd (path); var stream = new UnixInputStream (fd, true); @@ -356,6 +340,10 @@ public class About.FwupdManager : Object { on_error (device.update_error); } + if (details.image != null) { + details.image = yield download_file (details.image); + } + return details; } diff --git a/src/Widgets/FirmwareUpdateWidget.vala b/src/Widgets/FirmwareUpdateWidget.vala index fcc771dc3..2763e08fb 100644 --- a/src/Widgets/FirmwareUpdateWidget.vala +++ b/src/Widgets/FirmwareUpdateWidget.vala @@ -66,8 +66,8 @@ public class About.Widgets.FirmwareUpdateWidget : Gtk.ListBoxRow { update_button.clicked.connect (() => { on_update_start (); - FwupdManager.get_instance ().install.begin (device, device.latest_release, (obj, res) => { - FwupdManager.get_instance ().install.end (res); + update.begin (device, device.latest_release, (obj, res) => { + update.end (res); on_update_end (); }); }); @@ -87,4 +87,39 @@ public class About.Widgets.FirmwareUpdateWidget : Gtk.ListBoxRow { }; grid.attach (update_to_date_label, 2, 0, 1, 2); } + + private async void update (Device device, Release release) { + var path = yield FwupdManager.get_instance ().download_file (release.uri); + + var details = yield FwupdManager.get_instance ().get_details (device, path); + + if (details.caption != null) { + on_details (details); + } + + yield FwupdManager.get_instance ().install (device, path); + } + + private void on_details (Details details) { + var message_dialog = new Granite.MessageDialog.with_image_from_icon_name ( + _("Manual steps required"), + details.caption, + "application-x-firmware", + Gtk.ButtonsType.NONE + ); + + var suggested_button = new Gtk.Button.with_label (_("OK")); + suggested_button.get_style_context ().add_class (Gtk.STYLE_CLASS_SUGGESTED_ACTION); + message_dialog.add_action_widget (suggested_button, Gtk.ResponseType.OK); + + if (details.image != null) { + var custom_widget = new Gtk.Image.from_file (details.image); + message_dialog.custom_bin.add (custom_widget); + } + + message_dialog.badge_icon = new ThemedIcon ("dialog-information"); + message_dialog.show_all (); + message_dialog.run (); + message_dialog.destroy (); + } } From c13493b23123eb43a8e714cc865a17a8eb592cd2 Mon Sep 17 00:00:00 2001 From: Marius Meisenzahl Date: Thu, 14 Jan 2021 21:47:27 +0100 Subject: [PATCH 55/96] Set transient_for --- src/Views/FirmwareView.vala | 1 + src/Widgets/FirmwareUpdateWidget.vala | 1 + 2 files changed, 2 insertions(+) diff --git a/src/Views/FirmwareView.vala b/src/Views/FirmwareView.vala index 254dbae04..1cc51cd46 100644 --- a/src/Views/FirmwareView.vala +++ b/src/Views/FirmwareView.vala @@ -149,6 +149,7 @@ public class About.FirmwareView : Granite.SettingsPage { "application-x-firmware", Gtk.ButtonsType.CLOSE ); + message_dialog.transient_for = (Gtk.Window) get_toplevel (); message_dialog.badge_icon = new ThemedIcon ("dialog-error"); message_dialog.show_all (); message_dialog.run (); diff --git a/src/Widgets/FirmwareUpdateWidget.vala b/src/Widgets/FirmwareUpdateWidget.vala index 2763e08fb..961c0743a 100644 --- a/src/Widgets/FirmwareUpdateWidget.vala +++ b/src/Widgets/FirmwareUpdateWidget.vala @@ -107,6 +107,7 @@ public class About.Widgets.FirmwareUpdateWidget : Gtk.ListBoxRow { "application-x-firmware", Gtk.ButtonsType.NONE ); + message_dialog.transient_for = (Gtk.Window) get_toplevel (); var suggested_button = new Gtk.Button.with_label (_("OK")); suggested_button.get_style_context ().add_class (Gtk.STYLE_CLASS_SUGGESTED_ACTION); From acf30163557941060057af723d172bddf41f0961 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20For=C3=A9?= Date: Fri, 15 Jan 2021 10:13:29 -0800 Subject: [PATCH 56/96] Use listbox placeholder (#167) --- src/Views/FirmwareView.vala | 20 +++++--------------- 1 file changed, 5 insertions(+), 15 deletions(-) diff --git a/src/Views/FirmwareView.vala b/src/Views/FirmwareView.vala index 1cc51cd46..172a9dc54 100644 --- a/src/Views/FirmwareView.vala +++ b/src/Views/FirmwareView.vala @@ -23,7 +23,6 @@ public class About.FirmwareView : Granite.SettingsPage { private Gtk.Stack stack; private Gtk.Grid grid; private Gtk.Grid progress_view; - private Gtk.Grid no_devices_view; private Gtk.ListBox update_list; public FirmwareView () { @@ -47,17 +46,13 @@ public class About.FirmwareView : Granite.SettingsPage { progress_view.attach (progress_alert_view, 0, 0); var no_devices_alert_view = new Granite.Widgets.AlertView ( - _("No updatable devices"), + _("No Updatable Devices"), _("Firmware updates are not supported on this or any connected devices."), - "application-x-firmware" + "" ); + no_devices_alert_view.show_all (); no_devices_alert_view.get_style_context ().remove_class (Gtk.STYLE_CLASS_VIEW); - no_devices_view = new Gtk.Grid () { - margin = 24 - }; - no_devices_view.attach (no_devices_alert_view, 0, 0); - var header_icon = new Gtk.Image.from_icon_name ("application-x-firmware", Gtk.IconSize.DIALOG) { pixel_size = 48, valign = Gtk.Align.START @@ -75,6 +70,7 @@ public class About.FirmwareView : Granite.SettingsPage { vexpand = true, selection_mode = Gtk.SelectionMode.SINGLE }; + update_list.set_placeholder (no_devices_alert_view); var scrolled_window = new Gtk.ScrolledWindow (null, null); scrolled_window.add (update_list); @@ -96,7 +92,6 @@ public class About.FirmwareView : Granite.SettingsPage { stack.add (grid); stack.add (progress_view); - stack.add (no_devices_view); add (stack); @@ -119,12 +114,7 @@ public class About.FirmwareView : Granite.SettingsPage { } } - if (devices.length () == 0) { - stack.visible_child = no_devices_view; - return; - } else { - stack.visible_child = grid; - } + stack.visible_child = grid; foreach (var device in devices) { var widget = new Widgets.FirmwareUpdateWidget (device); From 365c5b699fd34431f3cf35c1fba28fd24cf42695 Mon Sep 17 00:00:00 2001 From: Marius Meisenzahl Date: Fri, 15 Jan 2021 19:33:06 +0100 Subject: [PATCH 57/96] Get rid of page header --- src/Views/FirmwareView.vala | 17 +---------------- 1 file changed, 1 insertion(+), 16 deletions(-) diff --git a/src/Views/FirmwareView.vala b/src/Views/FirmwareView.vala index 172a9dc54..a25b2c9cc 100644 --- a/src/Views/FirmwareView.vala +++ b/src/Views/FirmwareView.vala @@ -53,19 +53,6 @@ public class About.FirmwareView : Granite.SettingsPage { no_devices_alert_view.show_all (); no_devices_alert_view.get_style_context ().remove_class (Gtk.STYLE_CLASS_VIEW); - var header_icon = new Gtk.Image.from_icon_name ("application-x-firmware", Gtk.IconSize.DIALOG) { - pixel_size = 48, - valign = Gtk.Align.START - }; - - var title_label = new Gtk.Label (_("Firmware")) { - ellipsize = Pango.EllipsizeMode.END, - hexpand = true, - selectable = true, - xalign = 0 - }; - title_label.get_style_context ().add_class (Granite.STYLE_CLASS_H2_LABEL); - update_list = new Gtk.ListBox () { vexpand = true, selection_mode = Gtk.SelectionMode.SINGLE @@ -83,9 +70,7 @@ public class About.FirmwareView : Granite.SettingsPage { row_spacing = 12, margin = 12 }; - grid.attach (header_icon, 0, 0); - grid.attach (title_label, 1, 0); - grid.attach (frame, 0, 1, 3, 1); + grid.add (frame); stack = new Gtk.Stack (); stack.transition_type = Gtk.StackTransitionType.SLIDE_LEFT_RIGHT; From 5f98d6ff95c4b0793220b302d048cdaa68847022 Mon Sep 17 00:00:00 2001 From: Marius Meisenzahl Date: Fri, 15 Jan 2021 19:34:09 +0100 Subject: [PATCH 58/96] Add icon to list placeholder --- src/Views/FirmwareView.vala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Views/FirmwareView.vala b/src/Views/FirmwareView.vala index a25b2c9cc..c21a98ed5 100644 --- a/src/Views/FirmwareView.vala +++ b/src/Views/FirmwareView.vala @@ -48,7 +48,7 @@ public class About.FirmwareView : Granite.SettingsPage { var no_devices_alert_view = new Granite.Widgets.AlertView ( _("No Updatable Devices"), _("Firmware updates are not supported on this or any connected devices."), - "" + "application-x-firmware" ); no_devices_alert_view.show_all (); no_devices_alert_view.get_style_context ().remove_class (Gtk.STYLE_CLASS_VIEW); From f5589fb1f742c8120f188b716e83d61bc4638d5b Mon Sep 17 00:00:00 2001 From: Marius Meisenzahl Date: Fri, 15 Jan 2021 20:15:24 +0100 Subject: [PATCH 59/96] Show dialog to shutdown or reboot if needed --- src/Interfaces/FwupdManager.vala | 5 +- src/Interfaces/LoginManager.vala | 71 +++++++++++++++++++++++++++ src/Widgets/FirmwareUpdateWidget.vala | 56 +++++++++++++++++++-- src/meson.build | 3 +- 4 files changed, 130 insertions(+), 5 deletions(-) create mode 100644 src/Interfaces/LoginManager.vala diff --git a/src/Interfaces/FwupdManager.vala b/src/Interfaces/FwupdManager.vala index b94950bfe..ec3c5e9f7 100644 --- a/src/Interfaces/FwupdManager.vala +++ b/src/Interfaces/FwupdManager.vala @@ -250,7 +250,7 @@ public class About.FwupdManager : Object { return path; } - public async void install (Device device, string path) { + public async bool install (Device device, string path) { try { // https://github.com/fwupd/fwupd/blob/c0d4c09a02a40167e9de57f82c0033bb92e24167/libfwupd/fwupd-client.c#L2045 var options = new VariantBuilder (new VariantType ("a{sv}")); @@ -285,7 +285,10 @@ public class About.FwupdManager : Object { } catch (Error e) { warning ("Could not connect to fwupd interface: %s", e.message); on_error (device.update_error); + return false; } + + return true; } public async Details get_details (Device device, string path) { diff --git a/src/Interfaces/LoginManager.vala b/src/Interfaces/LoginManager.vala new file mode 100644 index 000000000..c5bea29ca --- /dev/null +++ b/src/Interfaces/LoginManager.vala @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2021 elementary, Inc. (https://elementary.io) + * + * 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 3 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 + * + * Authored by: Marius Meisenzahl + */ + +[DBus (name = "org.freedesktop.login1.Manager")] +public interface About.LoginInterface : Object { + public abstract void reboot (bool interactive) throws GLib.Error; + public abstract void power_off (bool interactive) throws GLib.Error; +} + +public class About.LoginManager : Object { + private LoginInterface interface; + + static LoginManager? instance = null; + public static LoginManager get_instance () { + if (instance == null) { + instance = new LoginManager (); + } + + return instance; + } + + private LoginManager () {} + + construct { + try { + interface = Bus.get_proxy_sync (BusType.SYSTEM, "org.freedesktop.login1", "/org/freedesktop/login1"); + } catch (Error e) { + warning ("Could not connect to login interface: %s", e.message); + } + } + + public bool shutdown () { + try { + interface.power_off (true); + } catch (Error e) { + warning ("Could not connect to login interface: %s", e.message); + return false; + } + + return true; + } + + public bool reboot () { + try { + interface.reboot (true); + } catch (Error e) { + warning ("Could not connect to login interface: %s", e.message); + return false; + } + + return true; + } +} diff --git a/src/Widgets/FirmwareUpdateWidget.vala b/src/Widgets/FirmwareUpdateWidget.vala index 961c0743a..8f4df7efe 100644 --- a/src/Widgets/FirmwareUpdateWidget.vala +++ b/src/Widgets/FirmwareUpdateWidget.vala @@ -94,13 +94,19 @@ public class About.Widgets.FirmwareUpdateWidget : Gtk.ListBoxRow { var details = yield FwupdManager.get_instance ().get_details (device, path); if (details.caption != null) { - on_details (details); + show_details_dialog (details); } - yield FwupdManager.get_instance ().install (device, path); + if ((yield FwupdManager.get_instance ().install (device, path)) == true) { + if (device.is (DeviceFlag.NEEDS_REBOOT)) { + show_reboot_dialog (); + } else if (device.is (DeviceFlag.NEEDS_SHUTDOWN)) { + show_shutdown_dialog (); + } + } } - private void on_details (Details details) { + private void show_details_dialog (Details details) { var message_dialog = new Granite.MessageDialog.with_image_from_icon_name ( _("Manual steps required"), details.caption, @@ -123,4 +129,48 @@ public class About.Widgets.FirmwareUpdateWidget : Gtk.ListBoxRow { message_dialog.run (); message_dialog.destroy (); } + + private void show_reboot_dialog () { + var message_dialog = new Granite.MessageDialog.with_image_from_icon_name ( + _("An update requires a reboot to complete"), + _("Reboot now?"), + "application-x-firmware", + Gtk.ButtonsType.CANCEL + ); + message_dialog.transient_for = (Gtk.Window) get_toplevel (); + + var suggested_button = new Gtk.Button.with_label (_("Reboot")); + suggested_button.get_style_context ().add_class (Gtk.STYLE_CLASS_SUGGESTED_ACTION); + message_dialog.add_action_widget (suggested_button, Gtk.ResponseType.OK); + + message_dialog.badge_icon = new ThemedIcon ("dialog-information"); + message_dialog.show_all (); + if (message_dialog.run () == Gtk.ResponseType.OK) { + LoginManager.get_instance ().reboot (); + } + + message_dialog.destroy (); + } + + private void show_shutdown_dialog () { + var message_dialog = new Granite.MessageDialog.with_image_from_icon_name ( + _("An update requires the system to shutdown to complete"), + _("Shutdown now?"), + "application-x-firmware", + Gtk.ButtonsType.CANCEL + ); + message_dialog.transient_for = (Gtk.Window) get_toplevel (); + + var suggested_button = new Gtk.Button.with_label (_("Shutdown")); + suggested_button.get_style_context ().add_class (Gtk.STYLE_CLASS_SUGGESTED_ACTION); + message_dialog.add_action_widget (suggested_button, Gtk.ResponseType.OK); + + message_dialog.badge_icon = new ThemedIcon ("dialog-information"); + message_dialog.show_all (); + if (message_dialog.run () == Gtk.ResponseType.OK) { + LoginManager.get_instance ().shutdown (); + } + + message_dialog.destroy (); + } } diff --git a/src/meson.build b/src/meson.build index 873607681..c61dbf84d 100644 --- a/src/meson.build +++ b/src/meson.build @@ -1,12 +1,13 @@ plug_files = files( 'fd.c', 'Plug.vala', + 'Interfaces/FwupdManager.vala', + 'Interfaces/LoginManager.vala', 'Objects/Details.vala', 'Objects/Device.vala', 'Objects/DeviceFlag.vala', 'Objects/Release.vala', 'Objects/ReleaseFlag.vala', - 'Interfaces/FwupdManager.vala', 'Utils/ARMPartDecoder.vala', 'Views/FirmwareView.vala', 'Views/HardwareView.vala', From 033ba8c80bbf39ac622df530bf366e91688b2e11 Mon Sep 17 00:00:00 2001 From: Marius Meisenzahl Date: Fri, 15 Jan 2021 21:50:11 +0100 Subject: [PATCH 60/96] Refactor --- src/Views/FirmwareView.vala | 27 ++++++++------------------- 1 file changed, 8 insertions(+), 19 deletions(-) diff --git a/src/Views/FirmwareView.vala b/src/Views/FirmwareView.vala index c21a98ed5..047dcebd3 100644 --- a/src/Views/FirmwareView.vala +++ b/src/Views/FirmwareView.vala @@ -19,20 +19,14 @@ * Authored by: Marius Meisenzahl */ -public class About.FirmwareView : Granite.SettingsPage { - private Gtk.Stack stack; +public class About.FirmwareView : Gtk.Stack { private Gtk.Grid grid; private Gtk.Grid progress_view; private Gtk.ListBox update_list; - public FirmwareView () { - Object ( - icon_name: "application-x-firmware", - title: _("Firmware") - ); - } - construct { + transition_type = Gtk.StackTransitionType.SLIDE_LEFT_RIGHT; + var progress_alert_view = new Granite.Widgets.AlertView ( _("Device is being updated"), _("Do not unplug the device during the update."), @@ -72,13 +66,8 @@ public class About.FirmwareView : Granite.SettingsPage { }; grid.add (frame); - stack = new Gtk.Stack (); - stack.transition_type = Gtk.StackTransitionType.SLIDE_LEFT_RIGHT; - - stack.add (grid); - stack.add (progress_view); - - add (stack); + add (grid); + add (progress_view); FwupdManager.get_instance ().on_error.connect (on_error); @@ -99,17 +88,17 @@ public class About.FirmwareView : Granite.SettingsPage { } } - stack.visible_child = grid; + visible_child = grid; foreach (var device in devices) { var widget = new Widgets.FirmwareUpdateWidget (device); update_list.add (widget); widget.on_update_start.connect (() => { - stack.visible_child = progress_view; + visible_child = progress_view; }); widget.on_update_end.connect (() => { - stack.visible_child = grid; + visible_child = grid; update_list_view.begin (); }); } From 463611bed6362fcb66fc1486a05c1ecc5a095a0b Mon Sep 17 00:00:00 2001 From: Marius Meisenzahl Date: Fri, 15 Jan 2021 21:52:46 +0100 Subject: [PATCH 61/96] Provide specifc error text --- src/Interfaces/FwupdManager.vala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Interfaces/FwupdManager.vala b/src/Interfaces/FwupdManager.vala index ec3c5e9f7..daba31969 100644 --- a/src/Interfaces/FwupdManager.vala +++ b/src/Interfaces/FwupdManager.vala @@ -284,7 +284,7 @@ public class About.FwupdManager : Object { ); } catch (Error e) { warning ("Could not connect to fwupd interface: %s", e.message); - on_error (device.update_error); + on_error (device.update_error != null ? device.update_error : e.message); return false; } From 27778bedbac1fdacf5d071869a4ed94fdab3e45d Mon Sep 17 00:00:00 2001 From: Marius Meisenzahl Date: Fri, 15 Jan 2021 21:58:01 +0100 Subject: [PATCH 62/96] Rename to FirmwareUpdateRow --- src/Views/FirmwareView.vala | 8 ++++---- .../{FirmwareUpdateWidget.vala => FirmwareUpdateRow.vala} | 4 ++-- src/meson.build | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) rename src/Widgets/{FirmwareUpdateWidget.vala => FirmwareUpdateRow.vala} (98%) diff --git a/src/Views/FirmwareView.vala b/src/Views/FirmwareView.vala index 047dcebd3..6579d7fb7 100644 --- a/src/Views/FirmwareView.vala +++ b/src/Views/FirmwareView.vala @@ -91,13 +91,13 @@ public class About.FirmwareView : Gtk.Stack { visible_child = grid; foreach (var device in devices) { - var widget = new Widgets.FirmwareUpdateWidget (device); - update_list.add (widget); + var row = new Widgets.FirmwareUpdateRow (device); + update_list.add (row); - widget.on_update_start.connect (() => { + row.on_update_start.connect (() => { visible_child = progress_view; }); - widget.on_update_end.connect (() => { + row.on_update_end.connect (() => { visible_child = grid; update_list_view.begin (); }); diff --git a/src/Widgets/FirmwareUpdateWidget.vala b/src/Widgets/FirmwareUpdateRow.vala similarity index 98% rename from src/Widgets/FirmwareUpdateWidget.vala rename to src/Widgets/FirmwareUpdateRow.vala index 8f4df7efe..0287cec4a 100644 --- a/src/Widgets/FirmwareUpdateWidget.vala +++ b/src/Widgets/FirmwareUpdateRow.vala @@ -19,13 +19,13 @@ * Authored by: Marius Meisenzahl */ -public class About.Widgets.FirmwareUpdateWidget : Gtk.ListBoxRow { +public class About.Widgets.FirmwareUpdateRow : Gtk.ListBoxRow { public Device device { get; construct set; } public signal void on_update_start (); public signal void on_update_end (); - public FirmwareUpdateWidget (Device device) { + public FirmwareUpdateRow (Device device) { Object (device: device); } diff --git a/src/meson.build b/src/meson.build index c61dbf84d..86ed135bc 100644 --- a/src/meson.build +++ b/src/meson.build @@ -12,7 +12,7 @@ plug_files = files( 'Views/FirmwareView.vala', 'Views/HardwareView.vala', 'Views/OperatingSystemView.vala', - 'Widgets/FirmwareUpdateWidget.vala' + 'Widgets/FirmwareUpdateRow.vala' ) switchboard_dep = dependency('switchboard-2.0') From 3c4adf076564ceb0948d84a1ad86291fe93463f1 Mon Sep 17 00:00:00 2001 From: Marius Meisenzahl Date: Fri, 15 Jan 2021 22:04:19 +0100 Subject: [PATCH 63/96] Be more verbose for shutdown and reboot --- src/Widgets/FirmwareUpdateRow.vala | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Widgets/FirmwareUpdateRow.vala b/src/Widgets/FirmwareUpdateRow.vala index 0287cec4a..5c38bdda8 100644 --- a/src/Widgets/FirmwareUpdateRow.vala +++ b/src/Widgets/FirmwareUpdateRow.vala @@ -133,14 +133,14 @@ public class About.Widgets.FirmwareUpdateRow : Gtk.ListBoxRow { private void show_reboot_dialog () { var message_dialog = new Granite.MessageDialog.with_image_from_icon_name ( _("An update requires a reboot to complete"), - _("Reboot now?"), + _("This will close all open applications and restart this device."), "application-x-firmware", Gtk.ButtonsType.CANCEL ); message_dialog.transient_for = (Gtk.Window) get_toplevel (); var suggested_button = new Gtk.Button.with_label (_("Reboot")); - suggested_button.get_style_context ().add_class (Gtk.STYLE_CLASS_SUGGESTED_ACTION); + suggested_button.get_style_context ().add_class (Gtk.STYLE_CLASS_DESTRUCTIVE_ACTION); message_dialog.add_action_widget (suggested_button, Gtk.ResponseType.OK); message_dialog.badge_icon = new ThemedIcon ("dialog-information"); @@ -155,14 +155,14 @@ public class About.Widgets.FirmwareUpdateRow : Gtk.ListBoxRow { private void show_shutdown_dialog () { var message_dialog = new Granite.MessageDialog.with_image_from_icon_name ( _("An update requires the system to shutdown to complete"), - _("Shutdown now?"), + _("This will close all open applications and turn off this device."), "application-x-firmware", Gtk.ButtonsType.CANCEL ); message_dialog.transient_for = (Gtk.Window) get_toplevel (); var suggested_button = new Gtk.Button.with_label (_("Shutdown")); - suggested_button.get_style_context ().add_class (Gtk.STYLE_CLASS_SUGGESTED_ACTION); + suggested_button.get_style_context ().add_class (Gtk.STYLE_CLASS_DESTRUCTIVE_ACTION); message_dialog.add_action_widget (suggested_button, Gtk.ResponseType.OK); message_dialog.badge_icon = new ThemedIcon ("dialog-information"); From 52a250d08defa14ab5fc63935036242aab2c9949 Mon Sep 17 00:00:00 2001 From: Marius Meisenzahl Date: Fri, 15 Jan 2021 22:13:53 +0100 Subject: [PATCH 64/96] Reduce number of iterations --- src/Views/FirmwareView.vala | 25 ++++++++++--------------- 1 file changed, 10 insertions(+), 15 deletions(-) diff --git a/src/Views/FirmwareView.vala b/src/Views/FirmwareView.vala index 6579d7fb7..2972ba5e6 100644 --- a/src/Views/FirmwareView.vala +++ b/src/Views/FirmwareView.vala @@ -81,28 +81,23 @@ public class About.FirmwareView : Gtk.Stack { } } - List devices = new List (); foreach (var device in yield FwupdManager.get_instance ().get_devices ()) { if (device.is (DeviceFlag.UPDATABLE) && device.releases.length () > 0) { - devices.append (device); + var row = new Widgets.FirmwareUpdateRow (device); + update_list.add (row); + + row.on_update_start.connect (() => { + visible_child = progress_view; + }); + row.on_update_end.connect (() => { + visible_child = grid; + update_list_view.begin (); + }); } } visible_child = grid; - foreach (var device in devices) { - var row = new Widgets.FirmwareUpdateRow (device); - update_list.add (row); - - row.on_update_start.connect (() => { - visible_child = progress_view; - }); - row.on_update_end.connect (() => { - visible_child = grid; - update_list_view.begin (); - }); - } - update_list.show_all (); } From 5d109cfefa4e34b7a252a84dd8c3132d132f7fdc Mon Sep 17 00:00:00 2001 From: Marius Meisenzahl Date: Fri, 15 Jan 2021 22:19:03 +0100 Subject: [PATCH 65/96] Provide a hopefully more understandable text --- src/Widgets/FirmwareUpdateRow.vala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Widgets/FirmwareUpdateRow.vala b/src/Widgets/FirmwareUpdateRow.vala index 5c38bdda8..4a34fe67a 100644 --- a/src/Widgets/FirmwareUpdateRow.vala +++ b/src/Widgets/FirmwareUpdateRow.vala @@ -115,7 +115,7 @@ public class About.Widgets.FirmwareUpdateRow : Gtk.ListBoxRow { ); message_dialog.transient_for = (Gtk.Window) get_toplevel (); - var suggested_button = new Gtk.Button.with_label (_("OK")); + var suggested_button = new Gtk.Button.with_label (_("Continue")); suggested_button.get_style_context ().add_class (Gtk.STYLE_CLASS_SUGGESTED_ACTION); message_dialog.add_action_widget (suggested_button, Gtk.ResponseType.OK); From 83bc8326923e61c4ca6ee83ef34ade4beb516eee Mon Sep 17 00:00:00 2001 From: Marius Meisenzahl Date: Fri, 15 Jan 2021 23:42:28 +0100 Subject: [PATCH 66/96] Apply suggestions from code review Co-authored-by: Cassidy James Blaede --- src/Objects/DeviceFlag.vala | 6 +++--- src/Widgets/FirmwareUpdateRow.vala | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Objects/DeviceFlag.vala b/src/Objects/DeviceFlag.vala index 9b44ff303..8cd9109df 100644 --- a/src/Objects/DeviceFlag.vala +++ b/src/Objects/DeviceFlag.vala @@ -218,7 +218,7 @@ public enum About.DeviceFlag { return _("Updatable"); case ONLY_OFFLINE: /* TRANSLATORS: Update can only be done from offline mode */ - return _("Update requires a reboot"); + return _("Update requires restarting the system"); case REQUIRE_AC: /* TRANSLATORS: Must be plugged in to an outlet */ return _("System requires external power source"); @@ -233,10 +233,10 @@ public enum About.DeviceFlag { return _("Requires a bootloader"); case NEEDS_REBOOT: /* TRANSLATORS: Requires a reboot to apply firmware or to reload hardware */ - return _("Needs a reboot after installation"); + return _("Update requires restarting the system"); case NEEDS_SHUTDOWN: /* TRANSLATORS: Requires system shutdown to apply firmware */ - return _("Needs shutdown after installation"); + return _("Requires the system to shut down after installation"); case REPORTED: /* TRANSLATORS: Has been reported to a metadata server */ return _("Reported to LVFS"); diff --git a/src/Widgets/FirmwareUpdateRow.vala b/src/Widgets/FirmwareUpdateRow.vala index 4a34fe67a..227975cef 100644 --- a/src/Widgets/FirmwareUpdateRow.vala +++ b/src/Widgets/FirmwareUpdateRow.vala @@ -132,7 +132,7 @@ public class About.Widgets.FirmwareUpdateRow : Gtk.ListBoxRow { private void show_reboot_dialog () { var message_dialog = new Granite.MessageDialog.with_image_from_icon_name ( - _("An update requires a reboot to complete"), + _("An update requires the system to restart to complete"), _("This will close all open applications and restart this device."), "application-x-firmware", Gtk.ButtonsType.CANCEL @@ -154,14 +154,14 @@ public class About.Widgets.FirmwareUpdateRow : Gtk.ListBoxRow { private void show_shutdown_dialog () { var message_dialog = new Granite.MessageDialog.with_image_from_icon_name ( - _("An update requires the system to shutdown to complete"), + _("An update requires the system to shut down to complete"), _("This will close all open applications and turn off this device."), "application-x-firmware", Gtk.ButtonsType.CANCEL ); message_dialog.transient_for = (Gtk.Window) get_toplevel (); - var suggested_button = new Gtk.Button.with_label (_("Shutdown")); + var suggested_button = new Gtk.Button.with_label (_("Shut Down")); suggested_button.get_style_context ().add_class (Gtk.STYLE_CLASS_DESTRUCTIVE_ACTION); message_dialog.add_action_widget (suggested_button, Gtk.ResponseType.OK); From ef91aa30399df1404177400fe2e5a2aab2600a7c Mon Sep 17 00:00:00 2001 From: Marius Meisenzahl Date: Fri, 15 Jan 2021 23:46:30 +0100 Subject: [PATCH 67/96] Update icons --- src/Widgets/FirmwareUpdateRow.vala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Widgets/FirmwareUpdateRow.vala b/src/Widgets/FirmwareUpdateRow.vala index 227975cef..8daf3eb08 100644 --- a/src/Widgets/FirmwareUpdateRow.vala +++ b/src/Widgets/FirmwareUpdateRow.vala @@ -143,7 +143,7 @@ public class About.Widgets.FirmwareUpdateRow : Gtk.ListBoxRow { suggested_button.get_style_context ().add_class (Gtk.STYLE_CLASS_DESTRUCTIVE_ACTION); message_dialog.add_action_widget (suggested_button, Gtk.ResponseType.OK); - message_dialog.badge_icon = new ThemedIcon ("dialog-information"); + message_dialog.badge_icon = new ThemedIcon ("system-reboot"); message_dialog.show_all (); if (message_dialog.run () == Gtk.ResponseType.OK) { LoginManager.get_instance ().reboot (); @@ -165,7 +165,7 @@ public class About.Widgets.FirmwareUpdateRow : Gtk.ListBoxRow { suggested_button.get_style_context ().add_class (Gtk.STYLE_CLASS_DESTRUCTIVE_ACTION); message_dialog.add_action_widget (suggested_button, Gtk.ResponseType.OK); - message_dialog.badge_icon = new ThemedIcon ("dialog-information"); + message_dialog.badge_icon = new ThemedIcon ("system-shutdown"); message_dialog.show_all (); if (message_dialog.run () == Gtk.ResponseType.OK) { LoginManager.get_instance ().shutdown (); From b8de755b18c66cb47476dbf499f5bbe06b0dd905 Mon Sep 17 00:00:00 2001 From: Marius Meisenzahl Date: Fri, 15 Jan 2021 23:52:45 +0100 Subject: [PATCH 68/96] Show name of device during update --- src/Views/FirmwareView.vala | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/Views/FirmwareView.vala b/src/Views/FirmwareView.vala index 2972ba5e6..f3ebb131f 100644 --- a/src/Views/FirmwareView.vala +++ b/src/Views/FirmwareView.vala @@ -21,14 +21,15 @@ public class About.FirmwareView : Gtk.Stack { private Gtk.Grid grid; + private Granite.Widgets.AlertView progress_alert_view; private Gtk.Grid progress_view; private Gtk.ListBox update_list; construct { transition_type = Gtk.StackTransitionType.SLIDE_LEFT_RIGHT; - var progress_alert_view = new Granite.Widgets.AlertView ( - _("Device is being updated"), + progress_alert_view = new Granite.Widgets.AlertView ( + "", _("Do not unplug the device during the update."), "emblem-synchronized" ); @@ -87,6 +88,7 @@ public class About.FirmwareView : Gtk.Stack { update_list.add (row); row.on_update_start.connect (() => { + progress_alert_view.title = _("“%s” is being updated".printf (device.name)); visible_child = progress_view; }); row.on_update_end.connect (() => { From d1c2cb74d8af3d075342b50ee57f550bcb7e4474 Mon Sep 17 00:00:00 2001 From: Marius Meisenzahl Date: Fri, 15 Jan 2021 23:54:30 +0100 Subject: [PATCH 69/96] Update button label Co-authored-by: Cassidy James Blaede --- src/Widgets/FirmwareUpdateRow.vala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Widgets/FirmwareUpdateRow.vala b/src/Widgets/FirmwareUpdateRow.vala index 8daf3eb08..b2fd7c005 100644 --- a/src/Widgets/FirmwareUpdateRow.vala +++ b/src/Widgets/FirmwareUpdateRow.vala @@ -139,7 +139,7 @@ public class About.Widgets.FirmwareUpdateRow : Gtk.ListBoxRow { ); message_dialog.transient_for = (Gtk.Window) get_toplevel (); - var suggested_button = new Gtk.Button.with_label (_("Reboot")); + var suggested_button = new Gtk.Button.with_label (_("Restart")); suggested_button.get_style_context ().add_class (Gtk.STYLE_CLASS_DESTRUCTIVE_ACTION); message_dialog.add_action_widget (suggested_button, Gtk.ResponseType.OK); From 8cb9f57c8d7a71d85e955047d97c2507507badc7 Mon Sep 17 00:00:00 2001 From: Marius Meisenzahl Date: Sat, 16 Jan 2021 07:06:34 +0100 Subject: [PATCH 70/96] Apply suggestions from code review MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Daniel Foré --- src/Views/FirmwareView.vala | 2 +- src/Widgets/FirmwareUpdateRow.vala | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Views/FirmwareView.vala b/src/Views/FirmwareView.vala index f3ebb131f..15c0ea885 100644 --- a/src/Views/FirmwareView.vala +++ b/src/Views/FirmwareView.vala @@ -107,7 +107,7 @@ public class About.FirmwareView : Gtk.Stack { var message_dialog = new Granite.MessageDialog.with_image_from_icon_name ( _("Failed to install firmware release"), error, - "application-x-firmware", + device.icon, Gtk.ButtonsType.CLOSE ); message_dialog.transient_for = (Gtk.Window) get_toplevel (); diff --git a/src/Widgets/FirmwareUpdateRow.vala b/src/Widgets/FirmwareUpdateRow.vala index b2fd7c005..ec0968d90 100644 --- a/src/Widgets/FirmwareUpdateRow.vala +++ b/src/Widgets/FirmwareUpdateRow.vala @@ -108,9 +108,9 @@ public class About.Widgets.FirmwareUpdateRow : Gtk.ListBoxRow { private void show_details_dialog (Details details) { var message_dialog = new Granite.MessageDialog.with_image_from_icon_name ( - _("Manual steps required"), + _("“%s” needs to manually be put in update mode").printf (device.name), details.caption, - "application-x-firmware", + device.icon, Gtk.ButtonsType.NONE ); message_dialog.transient_for = (Gtk.Window) get_toplevel (); From 8f6ccb41849fc53a76fd3c7134294b3b0b5f0322 Mon Sep 17 00:00:00 2001 From: Marius Meisenzahl Date: Sat, 16 Jan 2021 07:19:44 +0100 Subject: [PATCH 71/96] Use device icon if possible --- src/Interfaces/FwupdManager.vala | 10 +++++----- src/Views/FirmwareView.vala | 6 ++++-- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/src/Interfaces/FwupdManager.vala b/src/Interfaces/FwupdManager.vala index daba31969..354e90556 100644 --- a/src/Interfaces/FwupdManager.vala +++ b/src/Interfaces/FwupdManager.vala @@ -26,7 +26,7 @@ public class About.FwupdManager : Object { public signal void changed (); - public signal void on_error (string error); + public signal void on_error (string error, Device? device); static FwupdManager? instance = null; public static FwupdManager get_instance () { @@ -238,12 +238,12 @@ public class About.FwupdManager : Object { try { result = yield server_file.copy_async (local_file, FileCopyFlags.OVERWRITE, Priority.DEFAULT, null, (current_num_bytes, total_num_bytes) => {}); } catch (Error e) { - on_error ("Could not download file: %s".printf (e.message)); + on_error ("Could not download file: %s".printf (e.message), null); return null; } if (!result) { - on_error ("Download of %s was not succesfull".printf (uri)); + on_error ("Download of %s was not succesfull".printf (uri), null); return null; } @@ -284,7 +284,7 @@ public class About.FwupdManager : Object { ); } catch (Error e) { warning ("Could not connect to fwupd interface: %s", e.message); - on_error (device.update_error != null ? device.update_error : e.message); + on_error (device.update_error != null ? device.update_error : e.message, device); return false; } @@ -340,7 +340,7 @@ public class About.FwupdManager : Object { } } catch (Error e) { warning ("Could not connect to fwupd interface: %s", e.message); - on_error (device.update_error); + on_error (device.update_error, device); } if (details.image != null) { diff --git a/src/Views/FirmwareView.vala b/src/Views/FirmwareView.vala index 15c0ea885..2caf8e5fa 100644 --- a/src/Views/FirmwareView.vala +++ b/src/Views/FirmwareView.vala @@ -103,11 +103,13 @@ public class About.FirmwareView : Gtk.Stack { update_list.show_all (); } - private void on_error (string error) { + private void on_error (string error, Device? device) { + var icon = device != null ? device.icon : "application-x-firmware"; + var message_dialog = new Granite.MessageDialog.with_image_from_icon_name ( _("Failed to install firmware release"), error, - device.icon, + icon, Gtk.ButtonsType.CLOSE ); message_dialog.transient_for = (Gtk.Window) get_toplevel (); From a3d38b0733ee0e3efa324479149877f5faf25374 Mon Sep 17 00:00:00 2001 From: Marius Meisenzahl Date: Sat, 16 Jan 2021 07:24:42 +0100 Subject: [PATCH 72/96] Always provide device on error --- src/Interfaces/FwupdManager.vala | 14 +++++++------- src/Views/FirmwareView.vala | 8 +++----- src/Widgets/FirmwareUpdateRow.vala | 2 +- 3 files changed, 11 insertions(+), 13 deletions(-) diff --git a/src/Interfaces/FwupdManager.vala b/src/Interfaces/FwupdManager.vala index 354e90556..79bff4a51 100644 --- a/src/Interfaces/FwupdManager.vala +++ b/src/Interfaces/FwupdManager.vala @@ -26,7 +26,7 @@ public class About.FwupdManager : Object { public signal void changed (); - public signal void on_error (string error, Device? device); + public signal void on_device_error (Device device, string error); static FwupdManager? instance = null; public static FwupdManager get_instance () { @@ -224,7 +224,7 @@ public class About.FwupdManager : Object { return Path.build_path (Path.DIR_SEPARATOR_S, Environment.get_tmp_dir (), file_path); } - public async string? download_file (string uri) { + public async string? download_file (Device device, string uri) { var path = get_path (uri); File server_file = File.new_for_uri (uri); @@ -238,12 +238,12 @@ public class About.FwupdManager : Object { try { result = yield server_file.copy_async (local_file, FileCopyFlags.OVERWRITE, Priority.DEFAULT, null, (current_num_bytes, total_num_bytes) => {}); } catch (Error e) { - on_error ("Could not download file: %s".printf (e.message), null); + on_device_error (device, "Could not download file: %s".printf (e.message)); return null; } if (!result) { - on_error ("Download of %s was not succesfull".printf (uri), null); + on_device_error (device, "Download of %s was not succesfull".printf (uri)); return null; } @@ -284,7 +284,7 @@ public class About.FwupdManager : Object { ); } catch (Error e) { warning ("Could not connect to fwupd interface: %s", e.message); - on_error (device.update_error != null ? device.update_error : e.message, device); + on_device_error (device, device.update_error != null ? device.update_error : e.message); return false; } @@ -340,11 +340,11 @@ public class About.FwupdManager : Object { } } catch (Error e) { warning ("Could not connect to fwupd interface: %s", e.message); - on_error (device.update_error, device); + on_device_error (device, device.update_error); } if (details.image != null) { - details.image = yield download_file (details.image); + details.image = yield download_file (device, details.image); } return details; diff --git a/src/Views/FirmwareView.vala b/src/Views/FirmwareView.vala index 2caf8e5fa..7aebc25c9 100644 --- a/src/Views/FirmwareView.vala +++ b/src/Views/FirmwareView.vala @@ -70,7 +70,7 @@ public class About.FirmwareView : Gtk.Stack { add (grid); add (progress_view); - FwupdManager.get_instance ().on_error.connect (on_error); + FwupdManager.get_instance ().on_device_error.connect (on_device_error); update_list_view.begin (); } @@ -103,13 +103,11 @@ public class About.FirmwareView : Gtk.Stack { update_list.show_all (); } - private void on_error (string error, Device? device) { - var icon = device != null ? device.icon : "application-x-firmware"; - + private void on_device_error (Device device, string error) { var message_dialog = new Granite.MessageDialog.with_image_from_icon_name ( _("Failed to install firmware release"), error, - icon, + device.icon, Gtk.ButtonsType.CLOSE ); message_dialog.transient_for = (Gtk.Window) get_toplevel (); diff --git a/src/Widgets/FirmwareUpdateRow.vala b/src/Widgets/FirmwareUpdateRow.vala index ec0968d90..0343f1c40 100644 --- a/src/Widgets/FirmwareUpdateRow.vala +++ b/src/Widgets/FirmwareUpdateRow.vala @@ -89,7 +89,7 @@ public class About.Widgets.FirmwareUpdateRow : Gtk.ListBoxRow { } private async void update (Device device, Release release) { - var path = yield FwupdManager.get_instance ().download_file (release.uri); + var path = yield FwupdManager.get_instance ().download_file (device, release.uri); var details = yield FwupdManager.get_instance ().get_details (device, path); From 2227ae81da8dcc24282017df7e20f8aed6c765d5 Mon Sep 17 00:00:00 2001 From: Marius Meisenzahl Date: Sat, 16 Jan 2021 08:01:22 +0100 Subject: [PATCH 73/96] Reload when new device is plugged in --- src/Interfaces/FwupdManager.vala | 130 ++++++++++++++++++------------- src/Views/FirmwareView.vala | 39 ++++++---- 2 files changed, 104 insertions(+), 65 deletions(-) diff --git a/src/Interfaces/FwupdManager.vala b/src/Interfaces/FwupdManager.vala index 79bff4a51..f9b407414 100644 --- a/src/Interfaces/FwupdManager.vala +++ b/src/Interfaces/FwupdManager.vala @@ -26,6 +26,7 @@ public class About.FwupdManager : Object { public signal void changed (); + public signal void on_device_added (Device device); public signal void on_device_error (Device device, string error); static FwupdManager? instance = null; @@ -59,58 +60,7 @@ public class About.FwupdManager : Object { array_iter = element.iterator (); while ((element = array_iter.next_value ()) != null) { - GLib.Variant? val = null; - string? key = null; - - var device_iter = element.iterator (); - var device = new Device (); - while (device_iter.next ("{sv}", out key, out val)) { - switch (key) { - case "DeviceId": - device.id = val.get_string (); - break; - case "Flags": - device.flags = val.get_uint64 (); - if (device.id.length > 0 && device.is (DeviceFlag.UPDATABLE)) { - device.releases = yield get_releases (device.id); - } else { - device.releases = new List (); - } - break; - case "Name": - device.name = val.get_string (); - break; - case "Summary": - device.summary = val.get_string (); - break; - case "Vendor": - device.vendor = val.get_string (); - break; - case "VendorId": - if (device.vendor == null) { - device.vendor = val.get_string (); - } - break; - case "Version": - device.version = val.get_string (); - break; - case "Icon": - var icons = val.get_strv (); - device.icon = icons.length > 0 ? icons[0] : "application-x-firmware"; - break; - case "Guid": - device.guids = val.get_strv (); - break; - case "InstallDuration": - device.install_duration = val.get_uint32 (); - break; - case "UpdateError": - device.update_error = val.get_string (); - break; - default: - break; - } - } + var device = yield parse_device (element); devices_list.append (device); } } catch (Error e) { @@ -218,6 +168,62 @@ public class About.FwupdManager : Object { return releases_list; } + private async Device parse_device (Variant v) { + var device = new Device (); + var device_iter = v.iterator (); + GLib.Variant? val = null; + string? key = null; + while (device_iter.next ("{sv}", out key, out val)) { + switch (key) { + case "DeviceId": + device.id = val.get_string (); + break; + case "Flags": + device.flags = val.get_uint64 (); + if (device.id.length > 0 && device.is (DeviceFlag.UPDATABLE)) { + device.releases = yield get_releases (device.id); + } else { + device.releases = new List (); + } + break; + case "Name": + device.name = val.get_string (); + break; + case "Summary": + device.summary = val.get_string (); + break; + case "Vendor": + device.vendor = val.get_string (); + break; + case "VendorId": + if (device.vendor == null) { + device.vendor = val.get_string (); + } + break; + case "Version": + device.version = val.get_string (); + break; + case "Icon": + var icons = val.get_strv (); + device.icon = icons.length > 0 ? icons[0] : "application-x-firmware"; + break; + case "Guid": + device.guids = val.get_strv (); + break; + case "InstallDuration": + device.install_duration = val.get_uint32 (); + break; + case "UpdateError": + device.update_error = val.get_string (); + break; + default: + break; + } + } + + return device; + } + private string get_path (string uri) { var parts = uri.split ("/"); string file_path = parts[parts.length - 1]; @@ -353,6 +359,26 @@ public class About.FwupdManager : Object { construct { try { connection = Bus.get_sync (BusType.SYSTEM); + + connection.signal_subscribe ( + "org.freedesktop.fwupd", + "org.freedesktop.fwupd", + "DeviceAdded", + "/", + null, + DBusSignalFlags.NONE, + ((connection, sender_name, object_path, interface_name, signal_name, parameters) => { + var array_iter = parameters.iterator (); + GLib.Variant? element; + + while ((element = array_iter.next_value ()) != null) { + parse_device.begin (element, (obj, res) => { + var device = parse_device.end (res); + on_device_added (device); + }); + } + }) + ); } catch (Error e) { warning ("Could not connect to system bus: %s", e.message); } diff --git a/src/Views/FirmwareView.vala b/src/Views/FirmwareView.vala index 7aebc25c9..0b3128da0 100644 --- a/src/Views/FirmwareView.vala +++ b/src/Views/FirmwareView.vala @@ -70,6 +70,7 @@ public class About.FirmwareView : Gtk.Stack { add (grid); add (progress_view); + FwupdManager.get_instance ().on_device_added.connect (on_device_added); FwupdManager.get_instance ().on_device_error.connect (on_device_error); update_list_view.begin (); @@ -83,23 +84,35 @@ public class About.FirmwareView : Gtk.Stack { } foreach (var device in yield FwupdManager.get_instance ().get_devices ()) { - if (device.is (DeviceFlag.UPDATABLE) && device.releases.length () > 0) { - var row = new Widgets.FirmwareUpdateRow (device); - update_list.add (row); - - row.on_update_start.connect (() => { - progress_alert_view.title = _("“%s” is being updated".printf (device.name)); - visible_child = progress_view; - }); - row.on_update_end.connect (() => { - visible_child = grid; - update_list_view.begin (); - }); - } + add_device (device); } visible_child = grid; + update_list.show_all (); + } + private void add_device (Device device) { + if (device.is (DeviceFlag.UPDATABLE) && device.releases.length () > 0) { + var row = new Widgets.FirmwareUpdateRow (device); + update_list.add (row); + + row.on_update_start.connect (() => { + progress_alert_view.title = _("“%s” is being updated".printf (device.name)); + visible_child = progress_view; + }); + row.on_update_end.connect (() => { + visible_child = grid; + update_list_view.begin (); + }); + } + } + + private void on_device_added (Device device) { + debug ("Added device: %s", device.name); + + add_device (device); + + visible_child = grid; update_list.show_all (); } From 1900d60e9c8723a4ca50d6531e01fdb4e04f9a98 Mon Sep 17 00:00:00 2001 From: Marius Meisenzahl Date: Sat, 16 Jan 2021 08:10:09 +0100 Subject: [PATCH 74/96] Reload when device is removed --- src/Interfaces/FwupdManager.vala | 21 +++++++++++++++++++++ src/Views/FirmwareView.vala | 18 +++++++++++++++++- 2 files changed, 38 insertions(+), 1 deletion(-) diff --git a/src/Interfaces/FwupdManager.vala b/src/Interfaces/FwupdManager.vala index f9b407414..88d4952b4 100644 --- a/src/Interfaces/FwupdManager.vala +++ b/src/Interfaces/FwupdManager.vala @@ -28,6 +28,7 @@ public class About.FwupdManager : Object { public signal void on_device_added (Device device); public signal void on_device_error (Device device, string error); + public signal void on_device_removed (Device device); static FwupdManager? instance = null; public static FwupdManager get_instance () { @@ -379,6 +380,26 @@ public class About.FwupdManager : Object { } }) ); + + connection.signal_subscribe ( + "org.freedesktop.fwupd", + "org.freedesktop.fwupd", + "DeviceRemoved", + "/", + null, + DBusSignalFlags.NONE, + ((connection, sender_name, object_path, interface_name, signal_name, parameters) => { + var array_iter = parameters.iterator (); + GLib.Variant? element; + + while ((element = array_iter.next_value ()) != null) { + parse_device.begin (element, (obj, res) => { + var device = parse_device.end (res); + on_device_removed (device); + }); + } + }) + ); } catch (Error e) { warning ("Could not connect to system bus: %s", e.message); } diff --git a/src/Views/FirmwareView.vala b/src/Views/FirmwareView.vala index 0b3128da0..f5494ead1 100644 --- a/src/Views/FirmwareView.vala +++ b/src/Views/FirmwareView.vala @@ -72,13 +72,14 @@ public class About.FirmwareView : Gtk.Stack { FwupdManager.get_instance ().on_device_added.connect (on_device_added); FwupdManager.get_instance ().on_device_error.connect (on_device_error); + FwupdManager.get_instance ().on_device_removed.connect (on_device_removed); update_list_view.begin (); } private async void update_list_view () { foreach (unowned Gtk.Widget widget in update_list.get_children ()) { - if (widget is Gtk.ListBoxRow) { + if (widget is Widgets.FirmwareUpdateRow) { update_list.remove (widget); } } @@ -129,4 +130,19 @@ public class About.FirmwareView : Gtk.Stack { message_dialog.run (); message_dialog.destroy (); } + + private void on_device_removed (Device device) { + debug ("Removed device: %s", device.name); + + foreach (unowned Gtk.Widget widget in update_list.get_children ()) { + if (widget is Widgets.FirmwareUpdateRow) { + var row = (Widgets.FirmwareUpdateRow) widget; + if (row.device.id == device.id) { + update_list.remove (widget); + } + } + } + + update_list.show_all (); + } } From ca75aefcf609e158363d1e94ebc27855cd1d455a Mon Sep 17 00:00:00 2001 From: Marius Meisenzahl Date: Sat, 16 Jan 2021 08:14:50 +0100 Subject: [PATCH 75/96] Remove unused signal --- src/Interfaces/FwupdManager.vala | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/Interfaces/FwupdManager.vala b/src/Interfaces/FwupdManager.vala index 88d4952b4..9c2e4b9c1 100644 --- a/src/Interfaces/FwupdManager.vala +++ b/src/Interfaces/FwupdManager.vala @@ -24,8 +24,6 @@ extern int ro_fd (string path); public class About.FwupdManager : Object { private DBusConnection connection; - public signal void changed (); - public signal void on_device_added (Device device); public signal void on_device_error (Device device, string error); public signal void on_device_removed (Device device); From cb1389fcc1af7824f4dd840b0f2e17b5220f9265 Mon Sep 17 00:00:00 2001 From: Marius Meisenzahl Date: Tue, 19 Jan 2021 16:57:33 +0100 Subject: [PATCH 76/96] Use flags properly --- src/Interfaces/FwupdManager.vala | 6 +- src/Objects/Device.vala | 12 +-- src/Objects/DeviceFlag.vala | 140 +---------------------------- src/Objects/ReleaseFlag.vala | 30 +------ src/Views/FirmwareView.vala | 2 +- src/Widgets/FirmwareUpdateRow.vala | 4 +- 6 files changed, 11 insertions(+), 183 deletions(-) diff --git a/src/Interfaces/FwupdManager.vala b/src/Interfaces/FwupdManager.vala index 9c2e4b9c1..3584b0dac 100644 --- a/src/Interfaces/FwupdManager.vala +++ b/src/Interfaces/FwupdManager.vala @@ -146,7 +146,7 @@ public class About.FwupdManager : Object { release.license = val.get_string (); break; case "TrustFlags": - release.flag = ReleaseFlag.from_uint64 (val.get_uint64 ()); + release.flag = (ReleaseFlag) val.get_uint64 (); break; case "InstallDuration": release.install_duration = val.get_uint32 (); @@ -178,8 +178,8 @@ public class About.FwupdManager : Object { device.id = val.get_string (); break; case "Flags": - device.flags = val.get_uint64 (); - if (device.id.length > 0 && device.is (DeviceFlag.UPDATABLE)) { + device.flags = (DeviceFlag) val.get_uint64 (); + if (device.id.length > 0 && device.has_flag (DeviceFlag.UPDATABLE)) { device.releases = yield get_releases (device.id); } else { device.releases = new List (); diff --git a/src/Objects/Device.vala b/src/Objects/Device.vala index f77c3d97b..737f6ba4c 100644 --- a/src/Objects/Device.vala +++ b/src/Objects/Device.vala @@ -27,20 +27,14 @@ public class About.Device : Object { public string vendor { get; set; } public string version { get; set; } public string[] guids { get; set; } - public uint64 flags { get; set; } + public DeviceFlag flags { get; set; } public uint32 install_duration { get; set; } public string update_error { get; set; } public List releases { get; owned set; } public Release latest_release { get { return releases.nth_data (0); }} - public bool is (DeviceFlag flag) { - foreach (var f in DeviceFlag.get_list (flags)) { - if (f == flag) { - return true; - } - } - - return false; + public bool has_flag (DeviceFlag flag) { + return flag in flags; } } diff --git a/src/Objects/DeviceFlag.vala b/src/Objects/DeviceFlag.vala index 8cd9109df..ab0d2bf6c 100644 --- a/src/Objects/DeviceFlag.vala +++ b/src/Objects/DeviceFlag.vala @@ -20,6 +20,7 @@ */ // https://github.com/fwupd/fwupd/blob/72df1147933de747312aa7c9892f07e7916b8a39/libfwupd/fwupd-enums.h#L133 +[Flags] public enum About.DeviceFlag { NONE = (0u), /* Since: 0.1.3 */ INTERNAL = (1u << 0), /* Since: 0.1.3 */ @@ -66,145 +67,6 @@ public enum About.DeviceFlag { MD_SET_ICON = (1u << 41), /* Since: 1.5.2 */ UNKNOWN = uint64.MAX; /* Since: 0.7.3 */ - public static List get_list (uint64 flags) { - var list = new List (); - - if ((flags & (0u)) > 0) { - list.append (DeviceFlag.NONE); - } - if ((flags & (1u << 0)) > 0) { - list.append (DeviceFlag.INTERNAL); - } - if ((flags & (1u << 1)) > 0) { - list.append (DeviceFlag.UPDATABLE); - } - if ((flags & (1u << 2)) > 0) { - list.append (DeviceFlag.ONLY_OFFLINE); - } - if ((flags & (1u << 3)) > 0) { - list.append (DeviceFlag.REQUIRE_AC); - } - if ((flags & (1u << 4)) > 0) { - list.append (DeviceFlag.LOCKED); - } - if ((flags & (1u << 5)) > 0) { - list.append (DeviceFlag.SUPPORTED); - } - if ((flags & (1u << 6)) > 0) { - list.append (DeviceFlag.NEEDS_BOOTLOADER); - } - if ((flags & (1u << 7)) > 0) { - list.append (DeviceFlag.REGISTERED); - } - if ((flags & (1u << 8)) > 0) { - list.append (DeviceFlag.NEEDS_REBOOT); - } - if ((flags & (1u << 9)) > 0) { - list.append (DeviceFlag.REPORTED); - } - if ((flags & (1u << 10)) > 0) { - list.append (DeviceFlag.NOTIFIED); - } - if ((flags & (1u << 11)) > 0) { - list.append (DeviceFlag.USE_RUNTIME_VERSION); - } - if ((flags & (1u << 12)) > 0) { - list.append (DeviceFlag.INSTALL_PARENT_FIRST); - } - if ((flags & (1u << 13)) > 0) { - list.append (DeviceFlag.IS_BOOTLOADER); - } - if ((flags & (1u << 14)) > 0) { - list.append (DeviceFlag.WAIT_FOR_REPLUG); - } - if ((flags & (1u << 15)) > 0) { - list.append (DeviceFlag.IGNORE_VALIDATION); - } - if ((flags & (1u << 16)) > 0) { - list.append (DeviceFlag.TRUSTED); - } - if ((flags & (1u << 17)) > 0) { - list.append (DeviceFlag.NEEDS_SHUTDOWN); - } - if ((flags & (1u << 18)) > 0) { - list.append (DeviceFlag.ANOTHER_WRITE_REQUIRED); - } - if ((flags & (1u << 19)) > 0) { - list.append (DeviceFlag.NO_AUTO_INSTANCE_IDS); - } - if ((flags & (1u << 20)) > 0) { - list.append (DeviceFlag.NEEDS_ACTIVATION); - } - if ((flags & (1u << 21)) > 0) { - list.append (DeviceFlag.ENSURE_SEMVER); - } - if ((flags & (1u << 22)) > 0) { - list.append (DeviceFlag.HISTORICAL); - } - if ((flags & (1u << 23)) > 0) { - list.append (DeviceFlag.ONLY_SUPPORTED); - } - if ((flags & (1u << 24)) > 0) { - list.append (DeviceFlag.WILL_DISAPPEAR); - } - if ((flags & (1u << 25)) > 0) { - list.append (DeviceFlag.CAN_VERIFY); - } - if ((flags & (1u << 26)) > 0) { - list.append (DeviceFlag.CAN_VERIFY_IMAGE); - } - if ((flags & (1u << 27)) > 0) { - list.append (DeviceFlag.DUAL_IMAGE); - } - if ((flags & (1u << 28)) > 0) { - list.append (DeviceFlag.SELF_RECOVERY); - } - if ((flags & (1u << 29)) > 0) { - list.append (DeviceFlag.USABLE_DURING_UPDATE); - } - if ((flags & (1u << 30)) > 0) { - list.append (DeviceFlag.VERSION_CHECK_REQUIRED); - } - if ((flags & (1u << 31)) > 0) { - list.append (DeviceFlag.INSTALL_ALL_RELEASES); - } - if ((flags & (1u << 32)) > 0) { - list.append (DeviceFlag.MD_SET_NAME); - } - if ((flags & (1u << 33)) > 0) { - list.append (DeviceFlag.MD_SET_NAME_CATEGORY); - } - if ((flags & (1u << 34)) > 0) { - list.append (DeviceFlag.MD_SET_VERFMT); - } - if ((flags & (1u << 35)) > 0) { - list.append (DeviceFlag.ADD_COUNTERPART_GUIDS); - } - if ((flags & (1u << 36)) > 0) { - list.append (DeviceFlag.NO_GUID_MATCHING); - } - if ((flags & (1u << 37)) > 0) { - list.append (DeviceFlag.UPDATABLE_HIDDEN); - } - if ((flags & (1u << 38)) > 0) { - list.append (DeviceFlag.SKIPS_RESTART); - } - if ((flags & (1u << 39)) > 0) { - list.append (DeviceFlag.HAS_MULTIPLE_BRANCHES); - } - if ((flags & (1u << 40)) > 0) { - list.append (DeviceFlag.BACKUP_BEFORE_INSTALL); - } - if ((flags & (1u << 41)) > 0) { - list.append (DeviceFlag.MD_SET_ICON); - } - if ((flags & (uint64.MAX)) > 0) { - list.append (DeviceFlag.UNKNOWN); - } - - return list; - } - // https://gitlab.gnome.org/hughsie/gnome-firmware-updater/-/blob/f5281078e3cfade7ff919c812ba63de22431aaf2/src/gfu-common.c#L249 public string? to_string () { switch (this) { diff --git a/src/Objects/ReleaseFlag.vala b/src/Objects/ReleaseFlag.vala index 230db4e0c..27c8a20e2 100644 --- a/src/Objects/ReleaseFlag.vala +++ b/src/Objects/ReleaseFlag.vala @@ -20,6 +20,7 @@ */ // https://github.com/fwupd/fwupd/blob/72df1147933de747312aa7c9892f07e7916b8a39/libfwupd/fwupd-enums.h#L192 +[Flags] public enum About.ReleaseFlag { NONE = (0u), /* Since: 1.2.6 */ TRUSTED_PAYLOAD = (1u << 0), /* Since: 1.2.6 */ @@ -30,33 +31,4 @@ public enum About.ReleaseFlag { BLOCKED_APPROVAL = (1u << 5), /* Since: 1.2.6 */ IS_ALTERNATE_BRANCH = (1u << 6), /* Since: 1.5.0 */ UNKNOWN = uint64.MAX; /* Since: 1.2.6 */ - - public static ReleaseFlag from_uint64 (uint64 flag) { - if ((flag & (0u)) > 0) { - return ReleaseFlag.NONE; - } - else if ((flag & (1u << 0)) > 0) { - return ReleaseFlag.TRUSTED_PAYLOAD; - } - else if ((flag & (1u << 1)) > 0) { - return ReleaseFlag.TRUSTED_METADATA; - } - else if ((flag & (1u << 2)) > 0) { - return ReleaseFlag.IS_UPGRADE; - } - else if ((flag & (1u << 3)) > 0) { - return ReleaseFlag.IS_DOWNGRADE; - } - else if ((flag & (1u << 4)) > 0) { - return ReleaseFlag.BLOCKED_VERSION; - } - else if ((flag & (1u << 5)) > 0) { - return ReleaseFlag.BLOCKED_APPROVAL; - } - else if ((flag & (1u << 6)) > 0) { - return ReleaseFlag.IS_ALTERNATE_BRANCH; - } - - return ReleaseFlag.UNKNOWN; - } } diff --git a/src/Views/FirmwareView.vala b/src/Views/FirmwareView.vala index f5494ead1..44802b1e7 100644 --- a/src/Views/FirmwareView.vala +++ b/src/Views/FirmwareView.vala @@ -93,7 +93,7 @@ public class About.FirmwareView : Gtk.Stack { } private void add_device (Device device) { - if (device.is (DeviceFlag.UPDATABLE) && device.releases.length () > 0) { + if (device.has_flag (DeviceFlag.UPDATABLE) && device.releases.length () > 0) { var row = new Widgets.FirmwareUpdateRow (device); update_list.add (row); diff --git a/src/Widgets/FirmwareUpdateRow.vala b/src/Widgets/FirmwareUpdateRow.vala index 0343f1c40..892458d10 100644 --- a/src/Widgets/FirmwareUpdateRow.vala +++ b/src/Widgets/FirmwareUpdateRow.vala @@ -98,9 +98,9 @@ public class About.Widgets.FirmwareUpdateRow : Gtk.ListBoxRow { } if ((yield FwupdManager.get_instance ().install (device, path)) == true) { - if (device.is (DeviceFlag.NEEDS_REBOOT)) { + if (device.has_flag (DeviceFlag.NEEDS_REBOOT)) { show_reboot_dialog (); - } else if (device.is (DeviceFlag.NEEDS_SHUTDOWN)) { + } else if (device.has_flag (DeviceFlag.NEEDS_SHUTDOWN)) { show_shutdown_dialog (); } } From e93c94976dc52e8bba3dc2560fd9a7e1e6327085 Mon Sep 17 00:00:00 2001 From: David Hewitt Date: Tue, 19 Jan 2021 17:04:52 +0000 Subject: [PATCH 77/96] Refactor get_devices (#168) --- src/Interfaces/FwupdManager.vala | 104 +++++++++++-------------------- 1 file changed, 36 insertions(+), 68 deletions(-) diff --git a/src/Interfaces/FwupdManager.vala b/src/Interfaces/FwupdManager.vala index 3584b0dac..4ec9ad6f9 100644 --- a/src/Interfaces/FwupdManager.vala +++ b/src/Interfaces/FwupdManager.vala @@ -22,7 +22,16 @@ extern int ro_fd (string path); public class About.FwupdManager : Object { + [DBus (name = "org.freedesktop.fwupd")] + public interface FwupdInterface : Object { + public abstract signal void device_added (GLib.HashTable device); + public abstract signal void device_removed (GLib.HashTable device); + + public abstract async GLib.HashTable[] get_devices () throws GLib.Error; + } + private DBusConnection connection; + private FwupdInterface fwupd; public signal void on_device_added (Device device); public signal void on_device_error (Device device, string error); @@ -43,24 +52,9 @@ public class About.FwupdManager : Object { var devices_list = new List (); try { - var result = yield connection.call ( - "org.freedesktop.fwupd", - "/", - "org.freedesktop.fwupd", - "GetDevices", - null, - new VariantType ("(aa{sv})"), - DBusCallFlags.NONE, - -1 - ); - - var array_iter = result.iterator (); - GLib.Variant? element = array_iter.next_value (); - array_iter = element.iterator (); - - while ((element = array_iter.next_value ()) != null) { - var device = yield parse_device (element); - devices_list.append (device); + var result = yield fwupd.get_devices (); + foreach (unowned GLib.HashTable device in result) { + devices_list.append (yield parse_device (device)); } } catch (Error e) { warning ("Could not connect to fwupd interface: %s", e.message); @@ -167,23 +161,16 @@ public class About.FwupdManager : Object { return releases_list; } - private async Device parse_device (Variant v) { + private async Device parse_device (GLib.HashTable serialized_device) { var device = new Device (); - var device_iter = v.iterator (); - GLib.Variant? val = null; - string? key = null; - while (device_iter.next ("{sv}", out key, out val)) { + + serialized_device.@foreach ((key, val) => { switch (key) { case "DeviceId": device.id = val.get_string (); break; case "Flags": device.flags = (DeviceFlag) val.get_uint64 (); - if (device.id.length > 0 && device.has_flag (DeviceFlag.UPDATABLE)) { - device.releases = yield get_releases (device.id); - } else { - device.releases = new List (); - } break; case "Name": device.name = val.get_string (); @@ -218,6 +205,12 @@ public class About.FwupdManager : Object { default: break; } + }); + + if (device.id.length > 0 && device.has_flag (DeviceFlag.UPDATABLE)) { + device.releases = yield get_releases (device.id); + } else { + device.releases = new List (); } return device; @@ -358,46 +351,21 @@ public class About.FwupdManager : Object { construct { try { connection = Bus.get_sync (BusType.SYSTEM); - - connection.signal_subscribe ( - "org.freedesktop.fwupd", - "org.freedesktop.fwupd", - "DeviceAdded", - "/", - null, - DBusSignalFlags.NONE, - ((connection, sender_name, object_path, interface_name, signal_name, parameters) => { - var array_iter = parameters.iterator (); - GLib.Variant? element; - - while ((element = array_iter.next_value ()) != null) { - parse_device.begin (element, (obj, res) => { - var device = parse_device.end (res); - on_device_added (device); - }); - } - }) - ); - - connection.signal_subscribe ( - "org.freedesktop.fwupd", - "org.freedesktop.fwupd", - "DeviceRemoved", - "/", - null, - DBusSignalFlags.NONE, - ((connection, sender_name, object_path, interface_name, signal_name, parameters) => { - var array_iter = parameters.iterator (); - GLib.Variant? element; - - while ((element = array_iter.next_value ()) != null) { - parse_device.begin (element, (obj, res) => { - var device = parse_device.end (res); - on_device_removed (device); - }); - } - }) - ); + fwupd = Bus.get_proxy_sync (BusType.SYSTEM, "org.freedesktop.fwupd", "/"); + + fwupd.device_added.connect ((serialized_device) => { + parse_device.begin (serialized_device, (obj, res) => { + var device = parse_device.end (res); + on_device_added (device); + }); + }); + + fwupd.device_removed.connect ((serialized_device) => { + parse_device.begin (serialized_device, (obj, res) => { + var device = parse_device.end (res); + on_device_removed (device); + }); + }); } catch (Error e) { warning ("Could not connect to system bus: %s", e.message); } From c3e064cc666263fbce2a05ede2a02bce7621bdbf Mon Sep 17 00:00:00 2001 From: Marius Meisenzahl Date: Tue, 19 Jan 2021 18:32:19 +0100 Subject: [PATCH 78/96] Refactor get_releases --- src/Interfaces/FwupdManager.vala | 159 ++++++++++++++----------------- 1 file changed, 73 insertions(+), 86 deletions(-) diff --git a/src/Interfaces/FwupdManager.vala b/src/Interfaces/FwupdManager.vala index 4ec9ad6f9..5fbef0ece 100644 --- a/src/Interfaces/FwupdManager.vala +++ b/src/Interfaces/FwupdManager.vala @@ -28,6 +28,7 @@ public class About.FwupdManager : Object { public abstract signal void device_removed (GLib.HashTable device); public abstract async GLib.HashTable[] get_devices () throws GLib.Error; + public abstract async GLib.HashTable[] get_releases (string device_id) throws GLib.Error; } private DBusConnection connection; @@ -67,92 +68,9 @@ public class About.FwupdManager : Object { var releases_list = new List (); try { - var result = yield connection.call ( - "org.freedesktop.fwupd", - "/", - "org.freedesktop.fwupd", - "GetReleases", - new Variant ( - "(s)", - id - ), - new VariantType ("(aa{sv})"), - DBusCallFlags.NONE, - -1 - ); - - var array_iter = result.iterator (); - GLib.Variant? element = array_iter.next_value (); - array_iter = element.iterator (); - - while ((element = array_iter.next_value ()) != null) { - GLib.Variant? val = null; - string? key = null; - - var release_iter = element.iterator (); - var release = new Release (); - release.icon = "security-high"; - while (release_iter.next ("{sv}", out key, out val)) { - switch (key) { - case "Filename": - release.filename = val.get_string (); - break; - case "Name": - release.name = val.get_string (); - break; - case "Summary": - release.summary = val.get_string (); - break; - case "Version": - release.version = val.get_string (); - break; - case "Description": - release.description = val.get_string () - .replace ("

      ", "") - .replace ("

      ", "\n\n") - .replace ("
    2. ", " • ") - .replace ("
    3. ", "\n") - .replace ("
        ", "") - .replace ("
      ", "\n") - .replace ("
        ", "") // TODO: add support for ordered lists - .replace ("
      ", "\n") - .strip (); - break; - case "Protocol": - release.protocol = val.get_string (); - break; - case "RemoteId": - release.remote_id = val.get_string (); - break; - case "AppstreamId": - release.appstream_id = val.get_string (); - break; - case "Checksum": - release.checksum = val.get_string (); - break; - case "Vendor": - release.vendor = val.get_string (); - break; - case "Size": - release.size = val.get_uint64 (); - break; - case "License": - release.license = val.get_string (); - break; - case "TrustFlags": - release.flag = (ReleaseFlag) val.get_uint64 (); - break; - case "InstallDuration": - release.install_duration = val.get_uint32 (); - break; - case "Uri": - release.uri = val.get_string (); - break; - default: - break; - } - } - releases_list.append (release); + var result = yield fwupd.get_releases (id); + foreach (unowned GLib.HashTable release in result) { + releases_list.append (yield parse_release (release)); } } catch (Error e) { warning ("Could not connect to fwupd interface: %s", e.message); @@ -216,6 +134,75 @@ public class About.FwupdManager : Object { return device; } + private async Release parse_release (GLib.HashTable serialized_release) { + var release = new Release () { + icon = "security-high" + }; + + serialized_release.@foreach ((key, val) => { + switch (key) { + case "Filename": + release.filename = val.get_string (); + break; + case "Name": + release.name = val.get_string (); + break; + case "Summary": + release.summary = val.get_string (); + break; + case "Version": + release.version = val.get_string (); + break; + case "Description": + release.description = val.get_string () + .replace ("

      ", "") + .replace ("

      ", "\n\n") + .replace ("
    4. ", " • ") + .replace ("
    5. ", "\n") + .replace ("
        ", "") + .replace ("
      ", "\n") + .replace ("
        ", "") // TODO: add support for ordered lists + .replace ("
      ", "\n") + .strip (); + break; + case "Protocol": + release.protocol = val.get_string (); + break; + case "RemoteId": + release.remote_id = val.get_string (); + break; + case "AppstreamId": + release.appstream_id = val.get_string (); + break; + case "Checksum": + release.checksum = val.get_string (); + break; + case "Vendor": + release.vendor = val.get_string (); + break; + case "Size": + release.size = val.get_uint64 (); + break; + case "License": + release.license = val.get_string (); + break; + case "TrustFlags": + release.flag = (ReleaseFlag) val.get_uint64 (); + break; + case "InstallDuration": + release.install_duration = val.get_uint32 (); + break; + case "Uri": + release.uri = val.get_string (); + break; + default: + break; + } + }); + + return release; + } + private string get_path (string uri) { var parts = uri.split ("/"); string file_path = parts[parts.length - 1]; From ba53c538cf955195a1bf9bb23177b42c6c5473d9 Mon Sep 17 00:00:00 2001 From: Marius Meisenzahl Date: Tue, 19 Jan 2021 18:45:35 +0100 Subject: [PATCH 79/96] Refactor install --- src/Interfaces/FwupdManager.vala | 35 ++++++++------------------------ 1 file changed, 9 insertions(+), 26 deletions(-) diff --git a/src/Interfaces/FwupdManager.vala b/src/Interfaces/FwupdManager.vala index 5fbef0ece..175eb8bf6 100644 --- a/src/Interfaces/FwupdManager.vala +++ b/src/Interfaces/FwupdManager.vala @@ -29,6 +29,7 @@ public class About.FwupdManager : Object { public abstract async GLib.HashTable[] get_devices () throws GLib.Error; public abstract async GLib.HashTable[] get_releases (string device_id) throws GLib.Error; + public abstract async void install (string id, UnixInputStream handle, GLib.HashTable options) throws GLib.Error; } private DBusConnection connection; @@ -238,35 +239,17 @@ public class About.FwupdManager : Object { public async bool install (Device device, string path) { try { // https://github.com/fwupd/fwupd/blob/c0d4c09a02a40167e9de57f82c0033bb92e24167/libfwupd/fwupd-client.c#L2045 - var options = new VariantBuilder (new VariantType ("a{sv}")); - options.add ("{sv}", "reason", new Variant.string ("user-action")); - options.add ("{sv}", "filename", new Variant.string (path)); - options.add ("{sv}", "allow-older", new Variant.boolean (true)); - options.add ("{sv}", "allow-reinstall", new Variant.boolean (true)); - options.add ("{sv}", "no-history", new Variant.boolean (true)); + var options = new GLib.HashTable (str_hash, str_equal); + options.insert ("reason", new Variant.string ("user-action")); + options.insert ("filename", new Variant.string (path)); + options.insert ("allow-older", new Variant.boolean (true)); + options.insert ("allow-reinstall", new Variant.boolean (true)); + options.insert ("no-history", new Variant.boolean (true)); var fd = ro_fd (path); - var stream = new UnixInputStream (fd, true); - - var fd_list = new UnixFDList (); - fd_list.append (stream.fd); + var handle = new UnixInputStream (fd, true); - var parameters = new VariantBuilder (new VariantType ("(sha{sv})")); - parameters.add_value (new Variant.string (device.id)); - parameters.add_value (new Variant.handle (0)); - parameters.add_value (options.end ()); - - yield connection.call_with_unix_fd_list ( - "org.freedesktop.fwupd", - "/", - "org.freedesktop.fwupd", - "Install", - parameters.end (), - null, - DBusCallFlags.NONE, - -1, - fd_list - ); + yield fwupd.install (device.id, handle, options); } catch (Error e) { warning ("Could not connect to fwupd interface: %s", e.message); on_device_error (device, device.update_error != null ? device.update_error : e.message); From 92482924eadd297398667403c7c4a30f3177c058 Mon Sep 17 00:00:00 2001 From: Marius Meisenzahl Date: Tue, 19 Jan 2021 18:57:45 +0100 Subject: [PATCH 80/96] Refactor get_details --- src/Interfaces/FwupdManager.vala | 44 +++++++------------------------- 1 file changed, 9 insertions(+), 35 deletions(-) diff --git a/src/Interfaces/FwupdManager.vala b/src/Interfaces/FwupdManager.vala index 175eb8bf6..75188b8d7 100644 --- a/src/Interfaces/FwupdManager.vala +++ b/src/Interfaces/FwupdManager.vala @@ -30,9 +30,9 @@ public class About.FwupdManager : Object { public abstract async GLib.HashTable[] get_devices () throws GLib.Error; public abstract async GLib.HashTable[] get_releases (string device_id) throws GLib.Error; public abstract async void install (string id, UnixInputStream handle, GLib.HashTable options) throws GLib.Error; + public abstract async GLib.HashTable[] get_details (UnixInputStream handle) throws GLib.Error; } - private DBusConnection connection; private FwupdInterface fwupd; public signal void on_device_added (Device device); @@ -264,39 +264,14 @@ public class About.FwupdManager : Object { try { var fd = ro_fd (path); - var stream = new UnixInputStream (fd, true); - - var fd_list = new UnixFDList (); - fd_list.append (stream.fd); - - var parameters = new VariantBuilder (new VariantType ("(h)")); - parameters.add_value (new Variant.handle (0)); - - var r = yield connection.call_with_unix_fd_list ( - "org.freedesktop.fwupd", - "/", - "org.freedesktop.fwupd", - "GetDetails", - parameters.end (), - new VariantType ("(aa{sv})"), - DBusCallFlags.NONE, - -1, - fd_list - ); - - var array_iter = r.iterator (); - GLib.Variant? element = array_iter.next_value (); - array_iter = element.iterator (); - - while ((element = array_iter.next_value ()) != null) { - GLib.Variant? val = null; - string? key = null; - - var details_iter = element.iterator (); - while (details_iter.next ("{sv}", out key, out val)) { + var handle = new UnixInputStream (fd, true); + + var result = yield fwupd.get_details (handle); + foreach (unowned GLib.HashTable serialized_details in result) { + serialized_details.@foreach ((key, val) => { if (key == "Release") { - var release_iter = val.iterator ().next_value ().iterator (); - while (release_iter.next ("{sv}", out key, out val)) { + var iter = val.iterator ().next_value ().iterator (); + while (iter.next ("{sv}", out key, out val)) { if (key == "DetachCaption") { details.caption = val.get_string (); } else if (key == "DetachImage") { @@ -304,7 +279,7 @@ public class About.FwupdManager : Object { } } } - } + }); } } catch (Error e) { warning ("Could not connect to fwupd interface: %s", e.message); @@ -320,7 +295,6 @@ public class About.FwupdManager : Object { construct { try { - connection = Bus.get_sync (BusType.SYSTEM); fwupd = Bus.get_proxy_sync (BusType.SYSTEM, "org.freedesktop.fwupd", "/"); fwupd.device_added.connect ((serialized_device) => { From e09001ed87c008218531b5773d63dbaa712afb95 Mon Sep 17 00:00:00 2001 From: Marius Meisenzahl Date: Wed, 20 Jan 2021 18:23:12 +0100 Subject: [PATCH 81/96] Remove unnecessary async --- src/Interfaces/FwupdManager.vala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Interfaces/FwupdManager.vala b/src/Interfaces/FwupdManager.vala index 75188b8d7..54ad370ef 100644 --- a/src/Interfaces/FwupdManager.vala +++ b/src/Interfaces/FwupdManager.vala @@ -71,7 +71,7 @@ public class About.FwupdManager : Object { try { var result = yield fwupd.get_releases (id); foreach (unowned GLib.HashTable release in result) { - releases_list.append (yield parse_release (release)); + releases_list.append (parse_release (release)); } } catch (Error e) { warning ("Could not connect to fwupd interface: %s", e.message); @@ -135,7 +135,7 @@ public class About.FwupdManager : Object { return device; } - private async Release parse_release (GLib.HashTable serialized_release) { + private Release parse_release (GLib.HashTable serialized_release) { var release = new Release () { icon = "security-high" }; From c8b22a9419b4c594a3aa7dcae77b5b3d71a091cb Mon Sep 17 00:00:00 2001 From: Marius Meisenzahl Date: Wed, 20 Jan 2021 18:27:00 +0100 Subject: [PATCH 82/96] Use Posix.open --- src/Interfaces/FwupdManager.vala | 6 ++---- src/fd.c | 5 ----- src/meson.build | 1 - 3 files changed, 2 insertions(+), 10 deletions(-) delete mode 100644 src/fd.c diff --git a/src/Interfaces/FwupdManager.vala b/src/Interfaces/FwupdManager.vala index 54ad370ef..24e3f521f 100644 --- a/src/Interfaces/FwupdManager.vala +++ b/src/Interfaces/FwupdManager.vala @@ -19,8 +19,6 @@ * Authored by: Marius Meisenzahl */ -extern int ro_fd (string path); - public class About.FwupdManager : Object { [DBus (name = "org.freedesktop.fwupd")] public interface FwupdInterface : Object { @@ -246,7 +244,7 @@ public class About.FwupdManager : Object { options.insert ("allow-reinstall", new Variant.boolean (true)); options.insert ("no-history", new Variant.boolean (true)); - var fd = ro_fd (path); + var fd = Posix.open (path, Posix.O_RDONLY); var handle = new UnixInputStream (fd, true); yield fwupd.install (device.id, handle, options); @@ -263,7 +261,7 @@ public class About.FwupdManager : Object { var details = new Details (); try { - var fd = ro_fd (path); + var fd = Posix.open (path, Posix.O_RDONLY); var handle = new UnixInputStream (fd, true); var result = yield fwupd.get_details (handle); diff --git a/src/fd.c b/src/fd.c deleted file mode 100644 index 79aa23d48..000000000 --- a/src/fd.c +++ /dev/null @@ -1,5 +0,0 @@ -#include - -int ro_fd (const char *path) { - return open (path, O_RDONLY); -} diff --git a/src/meson.build b/src/meson.build index 86ed135bc..2504d9cfd 100644 --- a/src/meson.build +++ b/src/meson.build @@ -1,5 +1,4 @@ plug_files = files( - 'fd.c', 'Plug.vala', 'Interfaces/FwupdManager.vala', 'Interfaces/LoginManager.vala', From 004d844e519d0b3f3a70acd755c83db44051536b Mon Sep 17 00:00:00 2001 From: Marius Meisenzahl Date: Wed, 20 Jan 2021 18:32:27 +0100 Subject: [PATCH 83/96] Refactor namespace --- src/Interfaces/FwupdManager.vala | 38 +++++++++++++++--------------- src/Objects/Details.vala | 2 +- src/Objects/Device.vala | 4 ++-- src/Objects/DeviceFlag.vala | 2 +- src/Objects/Release.vala | 2 +- src/Objects/ReleaseFlag.vala | 2 +- src/Views/FirmwareView.vala | 10 ++++---- src/Widgets/FirmwareUpdateRow.vala | 14 +++++------ 8 files changed, 37 insertions(+), 37 deletions(-) diff --git a/src/Interfaces/FwupdManager.vala b/src/Interfaces/FwupdManager.vala index 24e3f521f..b83bfa652 100644 --- a/src/Interfaces/FwupdManager.vala +++ b/src/Interfaces/FwupdManager.vala @@ -33,9 +33,9 @@ public class About.FwupdManager : Object { private FwupdInterface fwupd; - public signal void on_device_added (Device device); - public signal void on_device_error (Device device, string error); - public signal void on_device_removed (Device device); + public signal void on_device_added (Fwupd.Device device); + public signal void on_device_error (Fwupd.Device device, string error); + public signal void on_device_removed (Fwupd.Device device); static FwupdManager? instance = null; public static FwupdManager get_instance () { @@ -48,8 +48,8 @@ public class About.FwupdManager : Object { private FwupdManager () {} - public async List get_devices () { - var devices_list = new List (); + public async List get_devices () { + var devices_list = new List (); try { var result = yield fwupd.get_devices (); @@ -63,8 +63,8 @@ public class About.FwupdManager : Object { return devices_list; } - private async List get_releases (string id) { - var releases_list = new List (); + private async List get_releases (string id) { + var releases_list = new List (); try { var result = yield fwupd.get_releases (id); @@ -78,8 +78,8 @@ public class About.FwupdManager : Object { return releases_list; } - private async Device parse_device (GLib.HashTable serialized_device) { - var device = new Device (); + private async Fwupd.Device parse_device (GLib.HashTable serialized_device) { + var device = new Fwupd.Device (); serialized_device.@foreach ((key, val) => { switch (key) { @@ -87,7 +87,7 @@ public class About.FwupdManager : Object { device.id = val.get_string (); break; case "Flags": - device.flags = (DeviceFlag) val.get_uint64 (); + device.flags = (Fwupd.DeviceFlag) val.get_uint64 (); break; case "Name": device.name = val.get_string (); @@ -124,17 +124,17 @@ public class About.FwupdManager : Object { } }); - if (device.id.length > 0 && device.has_flag (DeviceFlag.UPDATABLE)) { + if (device.id.length > 0 && device.has_flag (Fwupd.DeviceFlag.UPDATABLE)) { device.releases = yield get_releases (device.id); } else { - device.releases = new List (); + device.releases = new List (); } return device; } - private Release parse_release (GLib.HashTable serialized_release) { - var release = new Release () { + private Fwupd.Release parse_release (GLib.HashTable serialized_release) { + var release = new Fwupd.Release () { icon = "security-high" }; @@ -186,7 +186,7 @@ public class About.FwupdManager : Object { release.license = val.get_string (); break; case "TrustFlags": - release.flag = (ReleaseFlag) val.get_uint64 (); + release.flag = (Fwupd.ReleaseFlag) val.get_uint64 (); break; case "InstallDuration": release.install_duration = val.get_uint32 (); @@ -208,7 +208,7 @@ public class About.FwupdManager : Object { return Path.build_path (Path.DIR_SEPARATOR_S, Environment.get_tmp_dir (), file_path); } - public async string? download_file (Device device, string uri) { + public async string? download_file (Fwupd.Device device, string uri) { var path = get_path (uri); File server_file = File.new_for_uri (uri); @@ -234,7 +234,7 @@ public class About.FwupdManager : Object { return path; } - public async bool install (Device device, string path) { + public async bool install (Fwupd.Device device, string path) { try { // https://github.com/fwupd/fwupd/blob/c0d4c09a02a40167e9de57f82c0033bb92e24167/libfwupd/fwupd-client.c#L2045 var options = new GLib.HashTable (str_hash, str_equal); @@ -257,8 +257,8 @@ public class About.FwupdManager : Object { return true; } - public async Details get_details (Device device, string path) { - var details = new Details (); + public async Fwupd.Details get_details (Fwupd.Device device, string path) { + var details = new Fwupd.Details (); try { var fd = Posix.open (path, Posix.O_RDONLY); diff --git a/src/Objects/Details.vala b/src/Objects/Details.vala index 7d80a833a..770a1952c 100644 --- a/src/Objects/Details.vala +++ b/src/Objects/Details.vala @@ -19,7 +19,7 @@ * Authored by: Marius Meisenzahl */ -public class About.Details : Object { +public class Fwupd.Details : Object { public string caption { get; set; } public string image { get; set; } } diff --git a/src/Objects/Device.vala b/src/Objects/Device.vala index 737f6ba4c..87a4dd3a4 100644 --- a/src/Objects/Device.vala +++ b/src/Objects/Device.vala @@ -19,7 +19,7 @@ * Authored by: Marius Meisenzahl */ -public class About.Device : Object { +public class Fwupd.Device : Object { public string id { get; set; } public string name { get; set; } public string summary { get; set; } @@ -34,7 +34,7 @@ public class About.Device : Object { public List releases { get; owned set; } public Release latest_release { get { return releases.nth_data (0); }} - public bool has_flag (DeviceFlag flag) { + public bool has_flag (Fwupd.DeviceFlag flag) { return flag in flags; } } diff --git a/src/Objects/DeviceFlag.vala b/src/Objects/DeviceFlag.vala index ab0d2bf6c..3a70c2794 100644 --- a/src/Objects/DeviceFlag.vala +++ b/src/Objects/DeviceFlag.vala @@ -21,7 +21,7 @@ // https://github.com/fwupd/fwupd/blob/72df1147933de747312aa7c9892f07e7916b8a39/libfwupd/fwupd-enums.h#L133 [Flags] -public enum About.DeviceFlag { +public enum Fwupd.DeviceFlag { NONE = (0u), /* Since: 0.1.3 */ INTERNAL = (1u << 0), /* Since: 0.1.3 */ UPDATABLE = (1u << 1), /* Since: 0.9.7 */ diff --git a/src/Objects/Release.vala b/src/Objects/Release.vala index ced8a60b2..16920fe98 100644 --- a/src/Objects/Release.vala +++ b/src/Objects/Release.vala @@ -19,7 +19,7 @@ * Authored by: Marius Meisenzahl */ -public class About.Release : Object { +public class Fwupd.Release : Object { public string filename { get; set; } public string name { get; set; } public string summary { get; set; } diff --git a/src/Objects/ReleaseFlag.vala b/src/Objects/ReleaseFlag.vala index 27c8a20e2..f366b6cd4 100644 --- a/src/Objects/ReleaseFlag.vala +++ b/src/Objects/ReleaseFlag.vala @@ -21,7 +21,7 @@ // https://github.com/fwupd/fwupd/blob/72df1147933de747312aa7c9892f07e7916b8a39/libfwupd/fwupd-enums.h#L192 [Flags] -public enum About.ReleaseFlag { +public enum Fwupd.ReleaseFlag { NONE = (0u), /* Since: 1.2.6 */ TRUSTED_PAYLOAD = (1u << 0), /* Since: 1.2.6 */ TRUSTED_METADATA = (1u << 1), /* Since: 1.2.6 */ diff --git a/src/Views/FirmwareView.vala b/src/Views/FirmwareView.vala index 44802b1e7..61eb0ea8c 100644 --- a/src/Views/FirmwareView.vala +++ b/src/Views/FirmwareView.vala @@ -92,8 +92,8 @@ public class About.FirmwareView : Gtk.Stack { update_list.show_all (); } - private void add_device (Device device) { - if (device.has_flag (DeviceFlag.UPDATABLE) && device.releases.length () > 0) { + private void add_device (Fwupd.Device device) { + if (device.has_flag (Fwupd.DeviceFlag.UPDATABLE) && device.releases.length () > 0) { var row = new Widgets.FirmwareUpdateRow (device); update_list.add (row); @@ -108,7 +108,7 @@ public class About.FirmwareView : Gtk.Stack { } } - private void on_device_added (Device device) { + private void on_device_added (Fwupd.Device device) { debug ("Added device: %s", device.name); add_device (device); @@ -117,7 +117,7 @@ public class About.FirmwareView : Gtk.Stack { update_list.show_all (); } - private void on_device_error (Device device, string error) { + private void on_device_error (Fwupd.Device device, string error) { var message_dialog = new Granite.MessageDialog.with_image_from_icon_name ( _("Failed to install firmware release"), error, @@ -131,7 +131,7 @@ public class About.FirmwareView : Gtk.Stack { message_dialog.destroy (); } - private void on_device_removed (Device device) { + private void on_device_removed (Fwupd.Device device) { debug ("Removed device: %s", device.name); foreach (unowned Gtk.Widget widget in update_list.get_children ()) { diff --git a/src/Widgets/FirmwareUpdateRow.vala b/src/Widgets/FirmwareUpdateRow.vala index 892458d10..b11a95fe9 100644 --- a/src/Widgets/FirmwareUpdateRow.vala +++ b/src/Widgets/FirmwareUpdateRow.vala @@ -20,12 +20,12 @@ */ public class About.Widgets.FirmwareUpdateRow : Gtk.ListBoxRow { - public Device device { get; construct set; } + public Fwupd.Device device { get; construct set; } public signal void on_update_start (); public signal void on_update_end (); - public FirmwareUpdateRow (Device device) { + public FirmwareUpdateRow (Fwupd.Device device) { Object (device: device); } @@ -54,7 +54,7 @@ public class About.Widgets.FirmwareUpdateRow : Gtk.ListBoxRow { grid.attach (version_label, 1, 1); switch (device.latest_release.flag) { - case ReleaseFlag.IS_UPGRADE: + case Fwupd.ReleaseFlag.IS_UPGRADE: if (device.latest_release.version == device.version) { add_up_to_date_label (grid); break; @@ -88,7 +88,7 @@ public class About.Widgets.FirmwareUpdateRow : Gtk.ListBoxRow { grid.attach (update_to_date_label, 2, 0, 1, 2); } - private async void update (Device device, Release release) { + private async void update (Fwupd.Device device, Fwupd.Release release) { var path = yield FwupdManager.get_instance ().download_file (device, release.uri); var details = yield FwupdManager.get_instance ().get_details (device, path); @@ -98,15 +98,15 @@ public class About.Widgets.FirmwareUpdateRow : Gtk.ListBoxRow { } if ((yield FwupdManager.get_instance ().install (device, path)) == true) { - if (device.has_flag (DeviceFlag.NEEDS_REBOOT)) { + if (device.has_flag (Fwupd.DeviceFlag.NEEDS_REBOOT)) { show_reboot_dialog (); - } else if (device.has_flag (DeviceFlag.NEEDS_SHUTDOWN)) { + } else if (device.has_flag (Fwupd.DeviceFlag.NEEDS_SHUTDOWN)) { show_shutdown_dialog (); } } } - private void show_details_dialog (Details details) { + private void show_details_dialog (Fwupd.Details details) { var message_dialog = new Granite.MessageDialog.with_image_from_icon_name ( _("“%s” needs to manually be put in update mode").printf (device.name), details.caption, From cca55b9396f05a4bd4b4f4f1f46349bfe02ee9f2 Mon Sep 17 00:00:00 2001 From: Marius Meisenzahl Date: Wed, 20 Jan 2021 18:36:27 +0100 Subject: [PATCH 84/96] Refactor warning messages --- src/Interfaces/FwupdManager.vala | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Interfaces/FwupdManager.vala b/src/Interfaces/FwupdManager.vala index b83bfa652..23fc845b4 100644 --- a/src/Interfaces/FwupdManager.vala +++ b/src/Interfaces/FwupdManager.vala @@ -57,7 +57,7 @@ public class About.FwupdManager : Object { devices_list.append (yield parse_device (device)); } } catch (Error e) { - warning ("Could not connect to fwupd interface: %s", e.message); + warning ("Could not get devices: %s", e.message); } return devices_list; @@ -72,7 +72,7 @@ public class About.FwupdManager : Object { releases_list.append (parse_release (release)); } } catch (Error e) { - warning ("Could not connect to fwupd interface: %s", e.message); + warning ("Could not get releases for “%s”: %s", id, e.message); } return releases_list; @@ -249,7 +249,7 @@ public class About.FwupdManager : Object { yield fwupd.install (device.id, handle, options); } catch (Error e) { - warning ("Could not connect to fwupd interface: %s", e.message); + warning ("Could not install release for “%s”: %s", device.id, e.message); on_device_error (device, device.update_error != null ? device.update_error : e.message); return false; } @@ -280,7 +280,7 @@ public class About.FwupdManager : Object { }); } } catch (Error e) { - warning ("Could not connect to fwupd interface: %s", e.message); + warning ("Could not get details for “%s”: %s", device.id, e.message); on_device_error (device, device.update_error); } From 5224903516874d8c1ba0fdaf085a36d061d773ed Mon Sep 17 00:00:00 2001 From: Marius Meisenzahl Date: Wed, 20 Jan 2021 18:36:58 +0100 Subject: [PATCH 85/96] Make interface private --- src/Interfaces/FwupdManager.vala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Interfaces/FwupdManager.vala b/src/Interfaces/FwupdManager.vala index 23fc845b4..fb8bd3d4d 100644 --- a/src/Interfaces/FwupdManager.vala +++ b/src/Interfaces/FwupdManager.vala @@ -21,7 +21,7 @@ public class About.FwupdManager : Object { [DBus (name = "org.freedesktop.fwupd")] - public interface FwupdInterface : Object { + private interface FwupdInterface : Object { public abstract signal void device_added (GLib.HashTable device); public abstract signal void device_removed (GLib.HashTable device); From 79592ef6f147ee513348fd4d2dd5f45b63a815a4 Mon Sep 17 00:00:00 2001 From: Marius Meisenzahl Date: Wed, 20 Jan 2021 18:39:46 +0100 Subject: [PATCH 86/96] Refactor to use different variables --- src/Interfaces/FwupdManager.vala | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/Interfaces/FwupdManager.vala b/src/Interfaces/FwupdManager.vala index fb8bd3d4d..df4d829e9 100644 --- a/src/Interfaces/FwupdManager.vala +++ b/src/Interfaces/FwupdManager.vala @@ -269,11 +269,13 @@ public class About.FwupdManager : Object { serialized_details.@foreach ((key, val) => { if (key == "Release") { var iter = val.iterator ().next_value ().iterator (); - while (iter.next ("{sv}", out key, out val)) { - if (key == "DetachCaption") { - details.caption = val.get_string (); - } else if (key == "DetachImage") { - details.image = val.get_string (); + string details_key; + Variant details_val; + while (iter.next ("{sv}", out details_key, out details_val)) { + if (details_key == "DetachCaption") { + details.caption = details_val.get_string (); + } else if (details_key == "DetachImage") { + details.image = details_val.get_string (); } } } From 015396b7c5db49f45d56f353d06b1cb69c06a3da Mon Sep 17 00:00:00 2001 From: Marius Meisenzahl Date: Wed, 20 Jan 2021 18:43:33 +0100 Subject: [PATCH 87/96] Refactor translator comments --- src/Objects/DeviceFlag.vala | 42 ++++++++++++++++++------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/src/Objects/DeviceFlag.vala b/src/Objects/DeviceFlag.vala index 3a70c2794..e8921539c 100644 --- a/src/Objects/DeviceFlag.vala +++ b/src/Objects/DeviceFlag.vala @@ -73,52 +73,52 @@ public enum Fwupd.DeviceFlag { case NONE: return null; case INTERNAL: - /* TRANSLATORS: Device cannot be removed easily*/ + /// TRANSLATORS: Device cannot be removed easily return _("Internal device"); case UPDATABLE: - /* TRANSLATORS: Device is updatable in this or any other mode */ + /// TRANSLATORS: Device is updatable in this or any other mode return _("Updatable"); case ONLY_OFFLINE: - /* TRANSLATORS: Update can only be done from offline mode */ + /// TRANSLATORS: Update can only be done from offline mode return _("Update requires restarting the system"); case REQUIRE_AC: - /* TRANSLATORS: Must be plugged in to an outlet */ + /// TRANSLATORS: Must be plugged in to an outlet return _("System requires external power source"); case LOCKED: - /* TRANSLATORS: Is locked and can be unlocked */ + /// TRANSLATORS: Is locked and can be unlocked return _("Device is locked"); case SUPPORTED: - /* TRANSLATORS: Is found in current metadata */ + /// TRANSLATORS: Is found in current metadata return _("Supported on LVFS"); case NEEDS_BOOTLOADER: - /* TRANSLATORS: Requires a bootloader mode to be manually enabled by the user */ + /// TRANSLATORS: Requires a bootloader mode to be manually enabled by the user return _("Requires a bootloader"); case NEEDS_REBOOT: - /* TRANSLATORS: Requires a reboot to apply firmware or to reload hardware */ + /// TRANSLATORS: Requires a reboot to apply firmware or to reload hardware return _("Update requires restarting the system"); case NEEDS_SHUTDOWN: - /* TRANSLATORS: Requires system shutdown to apply firmware */ + /// TRANSLATORS: Requires system shutdown to apply firmware return _("Requires the system to shut down after installation"); case REPORTED: - /* TRANSLATORS: Has been reported to a metadata server */ + /// TRANSLATORS: Has been reported to a metadata server return _("Reported to LVFS"); case NOTIFIED: - /* TRANSLATORS: User has been notified */ + /// TRANSLATORS: User has been notified return _("User has been notified"); case USE_RUNTIME_VERSION: /* skip */ return null; case INSTALL_PARENT_FIRST: - /* TRANSLATORS: Install composite firmware on the parent before the child */ + /// TRANSLATORS: Install composite firmware on the parent before the child return _("Install to parent device first"); case IS_BOOTLOADER: - /* TRANSLATORS: Is currently in bootloader mode */ + /// TRANSLATORS: Is currently in bootloader mode return _("Is in bootloader mode"); case WAIT_FOR_REPLUG: - /* TRANSLATORS: The hardware is waiting to be replugged */ + /// TRANSLATORS: The hardware is waiting to be replugged return _("Hardware is waiting to be replugged"); case IGNORE_VALIDATION: - /* TRANSLATORS: Ignore validation safety checks when flashing this device */ + /// TRANSLATORS: Ignore validation safety checks when flashing this device return _("Ignore validation safety checks"); case ANOTHER_WRITE_REQUIRED: /* skip */ @@ -127,7 +127,7 @@ public enum Fwupd.DeviceFlag { /* skip */ return null; case NEEDS_ACTIVATION: - /* TRANSLATORS: Device update needs to be separately activated */ + /// TRANSLATORS: Device update needs to be separately activated return _("Device update needs activation"); case ENSURE_SEMVER: /* skip */ @@ -139,22 +139,22 @@ public enum Fwupd.DeviceFlag { /* skip */ return null; case WILL_DISAPPEAR: - /* TRANSLATORS: Device will not return after update completes */ + /// TRANSLATORS: Device will not return after update completes return _("Device will not re-appear after update completes"); case CAN_VERIFY: - /* TRANSLATORS: Device supports some form of checksum verification */ + /// TRANSLATORS: Device supports some form of checksum verification return _("Cryptographic hash verification is available"); case CAN_VERIFY_IMAGE: /* skip */ return null; case DUAL_IMAGE: - /* TRANSLATORS: Device supports a safety mechanism for flashing */ + /// TRANSLATORS: Device supports a safety mechanism for flashing return _("Device stages updates"); case SELF_RECOVERY: - /* TRANSLATORS: Device supports a safety mechanism for flashing */ + /// TRANSLATORS: Device supports a safety mechanism for flashing return _("Device can recover flash failures"); case USABLE_DURING_UPDATE: - /* TRANSLATORS: Device remains usable during update */ + /// TRANSLATORS: Device remains usable during update return _("Device is usable for the duration of the update"); case UNKNOWN: return null; From def4ec6335e6a3f8f9abb3a372e211c9a5c75263 Mon Sep 17 00:00:00 2001 From: Marius Meisenzahl Date: Wed, 20 Jan 2021 18:49:56 +0100 Subject: [PATCH 88/96] Add cancel button for details view --- src/Widgets/FirmwareUpdateRow.vala | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/src/Widgets/FirmwareUpdateRow.vala b/src/Widgets/FirmwareUpdateRow.vala index b11a95fe9..776f617c0 100644 --- a/src/Widgets/FirmwareUpdateRow.vala +++ b/src/Widgets/FirmwareUpdateRow.vala @@ -94,7 +94,9 @@ public class About.Widgets.FirmwareUpdateRow : Gtk.ListBoxRow { var details = yield FwupdManager.get_instance ().get_details (device, path); if (details.caption != null) { - show_details_dialog (details); + if (show_details_dialog (details) == false) { + return; + } } if ((yield FwupdManager.get_instance ().install (device, path)) == true) { @@ -106,18 +108,18 @@ public class About.Widgets.FirmwareUpdateRow : Gtk.ListBoxRow { } } - private void show_details_dialog (Fwupd.Details details) { + private bool show_details_dialog (Fwupd.Details details) { var message_dialog = new Granite.MessageDialog.with_image_from_icon_name ( _("“%s” needs to manually be put in update mode").printf (device.name), details.caption, device.icon, - Gtk.ButtonsType.NONE + Gtk.ButtonsType.CANCEL ); message_dialog.transient_for = (Gtk.Window) get_toplevel (); var suggested_button = new Gtk.Button.with_label (_("Continue")); suggested_button.get_style_context ().add_class (Gtk.STYLE_CLASS_SUGGESTED_ACTION); - message_dialog.add_action_widget (suggested_button, Gtk.ResponseType.OK); + message_dialog.add_action_widget (suggested_button, Gtk.ResponseType.ACCEPT); if (details.image != null) { var custom_widget = new Gtk.Image.from_file (details.image); @@ -126,8 +128,13 @@ public class About.Widgets.FirmwareUpdateRow : Gtk.ListBoxRow { message_dialog.badge_icon = new ThemedIcon ("dialog-information"); message_dialog.show_all (); - message_dialog.run (); + if (message_dialog.run () == Gtk.ResponseType.ACCEPT) { + return true; + } + message_dialog.destroy (); + + return false; } private void show_reboot_dialog () { @@ -141,11 +148,11 @@ public class About.Widgets.FirmwareUpdateRow : Gtk.ListBoxRow { var suggested_button = new Gtk.Button.with_label (_("Restart")); suggested_button.get_style_context ().add_class (Gtk.STYLE_CLASS_DESTRUCTIVE_ACTION); - message_dialog.add_action_widget (suggested_button, Gtk.ResponseType.OK); + message_dialog.add_action_widget (suggested_button, Gtk.ResponseType.ACCEPT); message_dialog.badge_icon = new ThemedIcon ("system-reboot"); message_dialog.show_all (); - if (message_dialog.run () == Gtk.ResponseType.OK) { + if (message_dialog.run () == Gtk.ResponseType.ACCEPT) { LoginManager.get_instance ().reboot (); } @@ -163,11 +170,11 @@ public class About.Widgets.FirmwareUpdateRow : Gtk.ListBoxRow { var suggested_button = new Gtk.Button.with_label (_("Shut Down")); suggested_button.get_style_context ().add_class (Gtk.STYLE_CLASS_DESTRUCTIVE_ACTION); - message_dialog.add_action_widget (suggested_button, Gtk.ResponseType.OK); + message_dialog.add_action_widget (suggested_button, Gtk.ResponseType.ACCEPT); message_dialog.badge_icon = new ThemedIcon ("system-shutdown"); message_dialog.show_all (); - if (message_dialog.run () == Gtk.ResponseType.OK) { + if (message_dialog.run () == Gtk.ResponseType.ACCEPT) { LoginManager.get_instance ().shutdown (); } From ac9f7e9c264c5283c3b0d081f8ec02ec441ef972 Mon Sep 17 00:00:00 2001 From: Marius Meisenzahl Date: Wed, 20 Jan 2021 18:57:16 +0100 Subject: [PATCH 89/96] Get rid of singleton --- src/Interfaces/FwupdManager.vala | 11 ----------- src/Views/FirmwareView.vala | 13 ++++++++----- src/Widgets/FirmwareUpdateRow.vala | 11 +++++++---- 3 files changed, 15 insertions(+), 20 deletions(-) diff --git a/src/Interfaces/FwupdManager.vala b/src/Interfaces/FwupdManager.vala index df4d829e9..203d7369c 100644 --- a/src/Interfaces/FwupdManager.vala +++ b/src/Interfaces/FwupdManager.vala @@ -37,17 +37,6 @@ public class About.FwupdManager : Object { public signal void on_device_error (Fwupd.Device device, string error); public signal void on_device_removed (Fwupd.Device device); - static FwupdManager? instance = null; - public static FwupdManager get_instance () { - if (instance == null) { - instance = new FwupdManager (); - } - - return instance; - } - - private FwupdManager () {} - public async List get_devices () { var devices_list = new List (); diff --git a/src/Views/FirmwareView.vala b/src/Views/FirmwareView.vala index 61eb0ea8c..38e0e8284 100644 --- a/src/Views/FirmwareView.vala +++ b/src/Views/FirmwareView.vala @@ -24,8 +24,11 @@ public class About.FirmwareView : Gtk.Stack { private Granite.Widgets.AlertView progress_alert_view; private Gtk.Grid progress_view; private Gtk.ListBox update_list; + private FwupdManager fwupd; construct { + fwupd = new FwupdManager (); + transition_type = Gtk.StackTransitionType.SLIDE_LEFT_RIGHT; progress_alert_view = new Granite.Widgets.AlertView ( @@ -70,9 +73,9 @@ public class About.FirmwareView : Gtk.Stack { add (grid); add (progress_view); - FwupdManager.get_instance ().on_device_added.connect (on_device_added); - FwupdManager.get_instance ().on_device_error.connect (on_device_error); - FwupdManager.get_instance ().on_device_removed.connect (on_device_removed); + fwupd.on_device_added.connect (on_device_added); + fwupd.on_device_error.connect (on_device_error); + fwupd.on_device_removed.connect (on_device_removed); update_list_view.begin (); } @@ -84,7 +87,7 @@ public class About.FirmwareView : Gtk.Stack { } } - foreach (var device in yield FwupdManager.get_instance ().get_devices ()) { + foreach (var device in yield fwupd.get_devices ()) { add_device (device); } @@ -94,7 +97,7 @@ public class About.FirmwareView : Gtk.Stack { private void add_device (Fwupd.Device device) { if (device.has_flag (Fwupd.DeviceFlag.UPDATABLE) && device.releases.length () > 0) { - var row = new Widgets.FirmwareUpdateRow (device); + var row = new Widgets.FirmwareUpdateRow (fwupd, device); update_list.add (row); row.on_update_start.connect (() => { diff --git a/src/Widgets/FirmwareUpdateRow.vala b/src/Widgets/FirmwareUpdateRow.vala index 776f617c0..452936047 100644 --- a/src/Widgets/FirmwareUpdateRow.vala +++ b/src/Widgets/FirmwareUpdateRow.vala @@ -20,13 +20,16 @@ */ public class About.Widgets.FirmwareUpdateRow : Gtk.ListBoxRow { + private FwupdManager fwupd; public Fwupd.Device device { get; construct set; } public signal void on_update_start (); public signal void on_update_end (); - public FirmwareUpdateRow (Fwupd.Device device) { + public FirmwareUpdateRow (FwupdManager fwupd, Fwupd.Device device) { Object (device: device); + + this.fwupd = fwupd; } construct { @@ -89,9 +92,9 @@ public class About.Widgets.FirmwareUpdateRow : Gtk.ListBoxRow { } private async void update (Fwupd.Device device, Fwupd.Release release) { - var path = yield FwupdManager.get_instance ().download_file (device, release.uri); + var path = yield fwupd.download_file (device, release.uri); - var details = yield FwupdManager.get_instance ().get_details (device, path); + var details = yield fwupd.get_details (device, path); if (details.caption != null) { if (show_details_dialog (details) == false) { @@ -99,7 +102,7 @@ public class About.Widgets.FirmwareUpdateRow : Gtk.ListBoxRow { } } - if ((yield FwupdManager.get_instance ().install (device, path)) == true) { + if ((yield fwupd.install (device, path)) == true) { if (device.has_flag (Fwupd.DeviceFlag.NEEDS_REBOOT)) { show_reboot_dialog (); } else if (device.has_flag (Fwupd.DeviceFlag.NEEDS_SHUTDOWN)) { From dc54b5a637270993dcd49be55b392bf00484d406 Mon Sep 17 00:00:00 2001 From: Marius Meisenzahl Date: Wed, 20 Jan 2021 19:00:43 +0100 Subject: [PATCH 90/96] Always download file --- src/Interfaces/FwupdManager.vala | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/Interfaces/FwupdManager.vala b/src/Interfaces/FwupdManager.vala index 203d7369c..21e1aec77 100644 --- a/src/Interfaces/FwupdManager.vala +++ b/src/Interfaces/FwupdManager.vala @@ -203,10 +203,6 @@ public class About.FwupdManager : Object { File server_file = File.new_for_uri (uri); File local_file = File.new_for_path (path); - if (FileUtils.test (path, FileTest.IS_REGULAR)) { - return path; - } - bool result; try { result = yield server_file.copy_async (local_file, FileCopyFlags.OVERWRITE, Priority.DEFAULT, null, (current_num_bytes, total_num_bytes) => {}); From 16072aaeafc2feb39218eb4c2a343143844a131a Mon Sep 17 00:00:00 2001 From: Marius Meisenzahl Date: Wed, 20 Jan 2021 19:06:30 +0100 Subject: [PATCH 91/96] Rename to get_release_details --- src/Interfaces/FwupdManager.vala | 2 +- src/Widgets/FirmwareUpdateRow.vala | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Interfaces/FwupdManager.vala b/src/Interfaces/FwupdManager.vala index 21e1aec77..639be9a25 100644 --- a/src/Interfaces/FwupdManager.vala +++ b/src/Interfaces/FwupdManager.vala @@ -242,7 +242,7 @@ public class About.FwupdManager : Object { return true; } - public async Fwupd.Details get_details (Fwupd.Device device, string path) { + public async Fwupd.Details get_release_details (Fwupd.Device device, string path) { var details = new Fwupd.Details (); try { diff --git a/src/Widgets/FirmwareUpdateRow.vala b/src/Widgets/FirmwareUpdateRow.vala index 452936047..c04939f8d 100644 --- a/src/Widgets/FirmwareUpdateRow.vala +++ b/src/Widgets/FirmwareUpdateRow.vala @@ -94,7 +94,7 @@ public class About.Widgets.FirmwareUpdateRow : Gtk.ListBoxRow { private async void update (Fwupd.Device device, Fwupd.Release release) { var path = yield fwupd.download_file (device, release.uri); - var details = yield fwupd.get_details (device, path); + var details = yield fwupd.get_release_details (device, path); if (details.caption != null) { if (show_details_dialog (details) == false) { From 5f4093d822074e1936366d299146d10914b64785 Mon Sep 17 00:00:00 2001 From: Marius Meisenzahl Date: Fri, 22 Jan 2021 18:07:41 +0100 Subject: [PATCH 92/96] Refactor get path of file --- src/Interfaces/FwupdManager.vala | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/src/Interfaces/FwupdManager.vala b/src/Interfaces/FwupdManager.vala index 639be9a25..a56042c13 100644 --- a/src/Interfaces/FwupdManager.vala +++ b/src/Interfaces/FwupdManager.vala @@ -191,16 +191,9 @@ public class About.FwupdManager : Object { return release; } - private string get_path (string uri) { - var parts = uri.split ("/"); - string file_path = parts[parts.length - 1]; - return Path.build_path (Path.DIR_SEPARATOR_S, Environment.get_tmp_dir (), file_path); - } - public async string? download_file (Fwupd.Device device, string uri) { - var path = get_path (uri); - File server_file = File.new_for_uri (uri); + var path = Path.build_filename (Environment.get_tmp_dir (), server_file.get_basename ()); File local_file = File.new_for_path (path); bool result; From 331022eeee9c8e8e212ac6776333b0d5ecfe3296 Mon Sep 17 00:00:00 2001 From: Marius Meisenzahl Date: Fri, 22 Jan 2021 18:09:39 +0100 Subject: [PATCH 93/96] Add TODO --- src/Interfaces/FwupdManager.vala | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Interfaces/FwupdManager.vala b/src/Interfaces/FwupdManager.vala index a56042c13..d824cfe0d 100644 --- a/src/Interfaces/FwupdManager.vala +++ b/src/Interfaces/FwupdManager.vala @@ -198,7 +198,9 @@ public class About.FwupdManager : Object { bool result; try { - result = yield server_file.copy_async (local_file, FileCopyFlags.OVERWRITE, Priority.DEFAULT, null, (current_num_bytes, total_num_bytes) => {}); + result = yield server_file.copy_async (local_file, FileCopyFlags.OVERWRITE, Priority.DEFAULT, null, (current_num_bytes, total_num_bytes) => { + // TODO: provide useful information for user + }); } catch (Error e) { on_device_error (device, "Could not download file: %s".printf (e.message)); return null; From a4b88089869f2d13571512c8473c95765895c868 Mon Sep 17 00:00:00 2001 From: Marius Meisenzahl Date: Fri, 22 Jan 2021 18:20:08 +0100 Subject: [PATCH 94/96] Close filedescriptor --- src/Interfaces/FwupdManager.vala | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/Interfaces/FwupdManager.vala b/src/Interfaces/FwupdManager.vala index d824cfe0d..bced866e5 100644 --- a/src/Interfaces/FwupdManager.vala +++ b/src/Interfaces/FwupdManager.vala @@ -215,6 +215,8 @@ public class About.FwupdManager : Object { } public async bool install (Fwupd.Device device, string path) { + int fd; + try { // https://github.com/fwupd/fwupd/blob/c0d4c09a02a40167e9de57f82c0033bb92e24167/libfwupd/fwupd-client.c#L2045 var options = new GLib.HashTable (str_hash, str_equal); @@ -224,7 +226,7 @@ public class About.FwupdManager : Object { options.insert ("allow-reinstall", new Variant.boolean (true)); options.insert ("no-history", new Variant.boolean (true)); - var fd = Posix.open (path, Posix.O_RDONLY); + fd = Posix.open (path, Posix.O_RDONLY); var handle = new UnixInputStream (fd, true); yield fwupd.install (device.id, handle, options); @@ -232,6 +234,8 @@ public class About.FwupdManager : Object { warning ("Could not install release for “%s”: %s", device.id, e.message); on_device_error (device, device.update_error != null ? device.update_error : e.message); return false; + } finally { + Posix.close (fd); } return true; @@ -240,8 +244,9 @@ public class About.FwupdManager : Object { public async Fwupd.Details get_release_details (Fwupd.Device device, string path) { var details = new Fwupd.Details (); + int fd; try { - var fd = Posix.open (path, Posix.O_RDONLY); + fd = Posix.open (path, Posix.O_RDONLY); var handle = new UnixInputStream (fd, true); var result = yield fwupd.get_details (handle); @@ -264,6 +269,8 @@ public class About.FwupdManager : Object { } catch (Error e) { warning ("Could not get details for “%s”: %s", device.id, e.message); on_device_error (device, device.update_error); + } finally { + Posix.close (fd); } if (details.image != null) { From bdb06770073d7f7dbd26890ea10912c919fa9991 Mon Sep 17 00:00:00 2001 From: Marius Meisenzahl Date: Fri, 22 Jan 2021 18:21:44 +0100 Subject: [PATCH 95/96] Refactor to use property --- src/Widgets/FirmwareUpdateRow.vala | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/Widgets/FirmwareUpdateRow.vala b/src/Widgets/FirmwareUpdateRow.vala index c04939f8d..695086134 100644 --- a/src/Widgets/FirmwareUpdateRow.vala +++ b/src/Widgets/FirmwareUpdateRow.vala @@ -20,16 +20,17 @@ */ public class About.Widgets.FirmwareUpdateRow : Gtk.ListBoxRow { - private FwupdManager fwupd; + public FwupdManager fwupd { get; construct set; } public Fwupd.Device device { get; construct set; } public signal void on_update_start (); public signal void on_update_end (); public FirmwareUpdateRow (FwupdManager fwupd, Fwupd.Device device) { - Object (device: device); - - this.fwupd = fwupd; + Object ( + fwupd: fwupd, + device: device + ); } construct { From bf25535a7ada0add7e192339c59a7813f325b5ec Mon Sep 17 00:00:00 2001 From: Marius Meisenzahl Date: Fri, 22 Jan 2021 18:26:01 +0100 Subject: [PATCH 96/96] Refactor dialog to decide if we want to continue the update --- src/Widgets/FirmwareUpdateRow.vala | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/Widgets/FirmwareUpdateRow.vala b/src/Widgets/FirmwareUpdateRow.vala index 695086134..bd1a65f70 100644 --- a/src/Widgets/FirmwareUpdateRow.vala +++ b/src/Widgets/FirmwareUpdateRow.vala @@ -132,13 +132,11 @@ public class About.Widgets.FirmwareUpdateRow : Gtk.ListBoxRow { message_dialog.badge_icon = new ThemedIcon ("dialog-information"); message_dialog.show_all (); - if (message_dialog.run () == Gtk.ResponseType.ACCEPT) { - return true; - } + bool should_continue = message_dialog.run () == Gtk.ResponseType.ACCEPT; message_dialog.destroy (); - return false; + return should_continue; } private void show_reboot_dialog () {