From 7437e990faa6af013b3cf2a1369feeed8aca9898 Mon Sep 17 00:00:00 2001 From: Leonhard Date: Wed, 7 Feb 2024 20:04:25 +0100 Subject: [PATCH 01/19] Add ubuntu drivers backend --- src/Application.vala | 1 + src/Backends/SystemUpdate.vala | 80 +-------------- src/Backends/UbuntuDrivers.vala | 170 ++++++++++++++++++++++++++++++++ src/Utils/PkUtils.vala | 78 +++++++++++++++ src/meson.build | 2 + 5 files changed, 253 insertions(+), 78 deletions(-) create mode 100644 src/Backends/UbuntuDrivers.vala create mode 100644 src/Utils/PkUtils.vala diff --git a/src/Application.vala b/src/Application.vala index 0014d548..3ec654b0 100644 --- a/src/Application.vala +++ b/src/Application.vala @@ -78,6 +78,7 @@ public sealed class SettingsDaemon.Application : Gtk.Application { base.dbus_register (connection, object_path); connection.register_object (object_path, new Backends.SystemUpdate ()); + connection.register_object (object_path, new Backends.UbuntuDrivers ()); return true; } diff --git a/src/Backends/SystemUpdate.vala b/src/Backends/SystemUpdate.vala index 8cbc4e8e..baf302a8 100644 --- a/src/Backends/SystemUpdate.vala +++ b/src/Backends/SystemUpdate.vala @@ -86,6 +86,7 @@ public class SettingsDaemon.Backends.SystemUpdate : Object { update_state (CHECKING); try { + //TODO: maybe check for prepared packages with Pk.offline_get_prepared_ids because it seems refreshing cache deletes prepared packages (which should only be a problem with drivers but still) yield task.refresh_cache_async (force, null, progress_callback); } catch (Error e) { warning ("Failed to refresh cache: %s", e.message); @@ -187,7 +188,7 @@ public class SettingsDaemon.Backends.SystemUpdate : Object { } private void progress_callback (Pk.Progress progress, Pk.ProgressType progress_type) { - update_state (current_state.state, status_to_title (progress.status)); + update_state (current_state.state, PkUtils.status_to_title (progress.status)); } private void send_error (string message) { @@ -210,83 +211,6 @@ public class SettingsDaemon.Backends.SystemUpdate : Object { state_changed (); } - private unowned string status_to_title (Pk.Status status) { - // From https://github.com/elementary/appcenter/blob/master/src/Core/ChangeInformation.vala#L51 - switch (status) { - case Pk.Status.SETUP: - return _("Starting"); - case Pk.Status.WAIT: - return _("Waiting"); - case Pk.Status.RUNNING: - return _("Running"); - case Pk.Status.QUERY: - return _("Querying"); - case Pk.Status.INFO: - return _("Getting information"); - case Pk.Status.REMOVE: - return _("Removing packages"); - case Pk.Status.DOWNLOAD: - return _("Downloading"); - case Pk.Status.REFRESH_CACHE: - return _("Refreshing software list"); - case Pk.Status.UPDATE: - return _("Installing updates"); - case Pk.Status.CLEANUP: - return _("Cleaning up packages"); - case Pk.Status.OBSOLETE: - return _("Obsoleting packages"); - case Pk.Status.DEP_RESOLVE: - return _("Resolving dependencies"); - case Pk.Status.SIG_CHECK: - return _("Checking signatures"); - case Pk.Status.TEST_COMMIT: - return _("Testing changes"); - case Pk.Status.COMMIT: - return _("Committing changes"); - case Pk.Status.REQUEST: - return _("Requesting data"); - case Pk.Status.FINISHED: - return _("Finished"); - case Pk.Status.CANCEL: - return _("Cancelling"); - case Pk.Status.DOWNLOAD_REPOSITORY: - return _("Downloading repository information"); - case Pk.Status.DOWNLOAD_PACKAGELIST: - return _("Downloading list of packages"); - case Pk.Status.DOWNLOAD_FILELIST: - return _("Downloading file lists"); - case Pk.Status.DOWNLOAD_CHANGELOG: - return _("Downloading lists of changes"); - case Pk.Status.DOWNLOAD_GROUP: - return _("Downloading groups"); - case Pk.Status.DOWNLOAD_UPDATEINFO: - return _("Downloading update information"); - case Pk.Status.REPACKAGING: - return _("Repackaging files"); - case Pk.Status.LOADING_CACHE: - return _("Loading cache"); - case Pk.Status.SCAN_APPLICATIONS: - return _("Scanning applications"); - case Pk.Status.GENERATE_PACKAGE_LIST: - return _("Generating package lists"); - case Pk.Status.WAITING_FOR_LOCK: - return _("Waiting for package manager lock"); - case Pk.Status.WAITING_FOR_AUTH: - return _("Waiting for authentication"); - case Pk.Status.SCAN_PROCESS_LIST: - return _("Updating running applications"); - case Pk.Status.CHECK_EXECUTABLE_FILES: - return _("Checking applications in use"); - case Pk.Status.CHECK_LIBRARIES: - return _("Checking libraries in use"); - case Pk.Status.COPY_FILES: - return _("Copying files"); - case Pk.Status.INSTALL: - default: - return _("Installing"); - } - } - public async CurrentState get_current_state () throws DBusError, IOError { return current_state; } diff --git a/src/Backends/UbuntuDrivers.vala b/src/Backends/UbuntuDrivers.vala new file mode 100644 index 00000000..98fbaf5c --- /dev/null +++ b/src/Backends/UbuntuDrivers.vala @@ -0,0 +1,170 @@ +/* + * Copyright 2023 elementary, Inc. (https://elementary.io) + * SPDX-License-Identifier: GPL-3.0-or-later + * + * Authored by: Leonhard Kargl + */ + +[DBus (name="io.elementary.settings_daemon.Drivers")] +public class SettingsDaemon.Backends.UbuntuDrivers : Object { + public enum State { + UP_TO_DATE, + CHECKING, + AVAILABLE, + DOWNLOADING, + RESTART_REQUIRED, + ERROR + } + + public struct CurrentState { + State state; + string status; + } + + private const string NOTIFICATION_ID = "drivers"; + + public signal void state_changed (); + + private CurrentState current_state; + private string[] available_drivers; + + private Pk.Task task; + private GLib.Cancellable cancellable; + + construct { + current_state = { + UP_TO_DATE, + "" + }; + + task = new Pk.Task () { + only_download = true + }; + + cancellable = new GLib.Cancellable (); + + check_for_drivers.begin (true); + } + + private async bool get_drivers_output (Cancellable? cancellable = null, out string? output = null) { + output = null; + string? drivers_exec_path = Environment.find_program_in_path ("ubuntu-drivers"); + if (drivers_exec_path == null) { + return false; + } + + Subprocess command; + try { + command = new Subprocess (SubprocessFlags.STDOUT_PIPE, drivers_exec_path, "list"); + yield command.communicate_utf8_async (null, cancellable, out output, null); + } catch (Error e) { + return false; + } + + return command.get_exit_status () == 0; + } + + public async void check_for_drivers (bool notify) throws DBusError, IOError { + if (current_state.state != UP_TO_DATE && current_state.state != AVAILABLE) { + return; + } + + update_state (CHECKING); + + string? command_output; + var result = yield get_drivers_output (cancellable, out command_output); + if (!result || command_output == null) { + update_state (UP_TO_DATE); + return; + } + + string[] tokens = command_output.split ("\n"); + available_drivers = {}; + foreach (unowned string token in tokens) { + if (token.strip () != "") { + available_drivers += token; + } + } + + if (available_drivers.length == 0) { + update_state (UP_TO_DATE); + return; + } + + update_state (AVAILABLE); + + if (notify) { + var notification = new Notification (_("Drivers available")); + notification.set_default_action (Application.ACTION_PREFIX + Application.SHOW_UPDATES_ACTION); + notification.set_body (_("For your system are drivers available")); + notification.set_icon (new ThemedIcon ("software-update-available")); + + GLib.Application.get_default ().send_notification (NOTIFICATION_ID, notification); + } + } + + public async void install (string pkg_name) throws DBusError, IOError { + cancellable.reset (); + + update_state (DOWNLOADING); + + try { + var results = yield task.install_packages_async ({ pkg_name }, cancellable, progress_callback); + + if (results.get_exit_code () == CANCELLED) { + debug ("Installation was cancelled"); + return; + } + + Pk.offline_trigger (REBOOT); + + var notification = new Notification (_("Restart required")); + notification.set_body (_("Please restart your system to finalize driver installation")); + notification.set_icon (new ThemedIcon ("system-reboot")); + notification.set_default_action (Application.ACTION_PREFIX + Application.SHOW_UPDATES_ACTION); + + GLib.Application.get_default ().send_notification (NOTIFICATION_ID, notification); + + update_state (RESTART_REQUIRED); + } catch (Error e) { + critical ("Failed to install driver: %s", e.message); + send_error (e.message); + } + } + + public void cancel () throws DBusError, IOError { + cancellable.cancel (); + } + + private void progress_callback (Pk.Progress progress, Pk.ProgressType progress_type) { + update_state (current_state.state, PkUtils.status_to_title (progress.status)); + } + + private void send_error (string message) { + var notification = new Notification (_("A driver couldn't be installed")); + notification.set_body (_("An error occurred while trying to install a driver")); + notification.set_icon (new ThemedIcon ("dialog-error")); + notification.set_default_action (Application.ACTION_PREFIX + Application.SHOW_UPDATES_ACTION); + + GLib.Application.get_default ().send_notification (NOTIFICATION_ID, notification); + + update_state (ERROR, message); + } + + private void update_state (State state, string message = "") { + current_state = { + state, + message + }; + + state_changed (); + } + + public async CurrentState get_current_state () throws DBusError, IOError { + return current_state; + } + + public async string[] get_available_drivers () throws DBusError, IOError { + return available_drivers; + } +} diff --git a/src/Utils/PkUtils.vala b/src/Utils/PkUtils.vala new file mode 100644 index 00000000..69362690 --- /dev/null +++ b/src/Utils/PkUtils.vala @@ -0,0 +1,78 @@ +namespace SettingsDaemon.PkUtils { + public static unowned string status_to_title (Pk.Status status) { + // From https://github.com/elementary/appcenter/blob/master/src/Core/ChangeInformation.vala#L51 + switch (status) { + case Pk.Status.SETUP: + return _("Starting"); + case Pk.Status.WAIT: + return _("Waiting"); + case Pk.Status.RUNNING: + return _("Running"); + case Pk.Status.QUERY: + return _("Querying"); + case Pk.Status.INFO: + return _("Getting information"); + case Pk.Status.REMOVE: + return _("Removing packages"); + case Pk.Status.DOWNLOAD: + return _("Downloading"); + case Pk.Status.REFRESH_CACHE: + return _("Refreshing software list"); + case Pk.Status.UPDATE: + return _("Installing updates"); + case Pk.Status.CLEANUP: + return _("Cleaning up packages"); + case Pk.Status.OBSOLETE: + return _("Obsoleting packages"); + case Pk.Status.DEP_RESOLVE: + return _("Resolving dependencies"); + case Pk.Status.SIG_CHECK: + return _("Checking signatures"); + case Pk.Status.TEST_COMMIT: + return _("Testing changes"); + case Pk.Status.COMMIT: + return _("Committing changes"); + case Pk.Status.REQUEST: + return _("Requesting data"); + case Pk.Status.FINISHED: + return _("Finished"); + case Pk.Status.CANCEL: + return _("Cancelling"); + case Pk.Status.DOWNLOAD_REPOSITORY: + return _("Downloading repository information"); + case Pk.Status.DOWNLOAD_PACKAGELIST: + return _("Downloading list of packages"); + case Pk.Status.DOWNLOAD_FILELIST: + return _("Downloading file lists"); + case Pk.Status.DOWNLOAD_CHANGELOG: + return _("Downloading lists of changes"); + case Pk.Status.DOWNLOAD_GROUP: + return _("Downloading groups"); + case Pk.Status.DOWNLOAD_UPDATEINFO: + return _("Downloading update information"); + case Pk.Status.REPACKAGING: + return _("Repackaging files"); + case Pk.Status.LOADING_CACHE: + return _("Loading cache"); + case Pk.Status.SCAN_APPLICATIONS: + return _("Scanning applications"); + case Pk.Status.GENERATE_PACKAGE_LIST: + return _("Generating package lists"); + case Pk.Status.WAITING_FOR_LOCK: + return _("Waiting for package manager lock"); + case Pk.Status.WAITING_FOR_AUTH: + return _("Waiting for authentication"); + case Pk.Status.SCAN_PROCESS_LIST: + return _("Updating running applications"); + case Pk.Status.CHECK_EXECUTABLE_FILES: + return _("Checking applications in use"); + case Pk.Status.CHECK_LIBRARIES: + return _("Checking libraries in use"); + case Pk.Status.COPY_FILES: + return _("Copying files"); + case Pk.Status.INSTALL: + default: + return _("Installing"); + } + } +} \ No newline at end of file diff --git a/src/meson.build b/src/meson.build index 05f2250f..d9a4ec86 100644 --- a/src/meson.build +++ b/src/meson.build @@ -9,6 +9,8 @@ sources = files( 'Backends/NightLightSettings.vala', 'Backends/PrefersColorSchemeSettings.vala', 'Backends/SystemUpdate.vala', + 'Backends/UbuntuDrivers.vala', + 'Utils/PkUtils.vala', 'Utils/SunriseSunsetCalculator.vala', ) From a24ca7eed237b9a08e753014af43529d623ae955 Mon Sep 17 00:00:00 2001 From: Leonhard Date: Wed, 7 Feb 2024 20:26:57 +0100 Subject: [PATCH 02/19] Copy more stuff from appcenter --- src/Backends/UbuntuDrivers.vala | 40 ++++++++++++++++++++++++++++----- 1 file changed, 34 insertions(+), 6 deletions(-) diff --git a/src/Backends/UbuntuDrivers.vala b/src/Backends/UbuntuDrivers.vala index 98fbaf5c..59ff71d9 100644 --- a/src/Backends/UbuntuDrivers.vala +++ b/src/Backends/UbuntuDrivers.vala @@ -26,7 +26,7 @@ public class SettingsDaemon.Backends.UbuntuDrivers : Object { public signal void state_changed (); private CurrentState current_state; - private string[] available_drivers; + private HashTable> available_drivers; private Pk.Task task; private GLib.Cancellable cancellable; @@ -37,6 +37,8 @@ public class SettingsDaemon.Backends.UbuntuDrivers : Object { "" }; + available_drivers = new HashTable> (str_hash, str_equal); + task = new Pk.Task () { only_download = true }; @@ -70,6 +72,7 @@ public class SettingsDaemon.Backends.UbuntuDrivers : Object { } update_state (CHECKING); + available_drivers.remove_all (); string? command_output; var result = yield get_drivers_output (cancellable, out command_output); @@ -79,11 +82,36 @@ public class SettingsDaemon.Backends.UbuntuDrivers : Object { } string[] tokens = command_output.split ("\n"); - available_drivers = {}; - foreach (unowned string token in tokens) { - if (token.strip () != "") { - available_drivers += token; + foreach (unowned string package_name in tokens) { + if (package_name.strip () == "") { + continue; + } + + // ubuntu-drivers returns lines like the following for dkms packages: + // backport-iwlwifi-dkms, (kernel modules provided by backport-iwlwifi-dkms) + // nvidia-driver-470, (kernel modules provided by linux-modules-nvidia-470-generic-hwe-20.04) + // we want to install both packages if they're different + + string[] parts = package_name.split (","); + // Get the driver part (before the comma) + var package_names = new GenericSet (str_hash, str_equal); + package_names.add (parts[0]); + + if (parts.length > 1) { + if (parts[1].contains ("kernel modules provided by")) { + string[] kernel_module_parts = parts[1].split (" "); + // Get the remainder of the string after the last space + var last_part = kernel_module_parts[kernel_module_parts.length - 1]; + // Strip off the trailing bracket + last_part = last_part.replace (")", ""); + + package_names.add (last_part); + } else { + warning ("Unrecognised line from ubuntu-drivers, needs checking: %s", package_name); + } } + + available_drivers[package_name] = package_names; } if (available_drivers.length == 0) { @@ -165,6 +193,6 @@ public class SettingsDaemon.Backends.UbuntuDrivers : Object { } public async string[] get_available_drivers () throws DBusError, IOError { - return available_drivers; + return available_drivers.get_keys_as_array (); } } From 37c45e3367bf71ada87ed1c847e0c6f7f6e70f25 Mon Sep 17 00:00:00 2001 From: Leonhard Date: Wed, 7 Feb 2024 20:31:36 +0100 Subject: [PATCH 03/19] DRY --- src/Backends/SystemUpdate.vala | 20 +++----------------- src/Backends/UbuntuDrivers.vala | 20 +++----------------- src/Utils/PkUtils.vala | 14 ++++++++++++++ 3 files changed, 20 insertions(+), 34 deletions(-) diff --git a/src/Backends/SystemUpdate.vala b/src/Backends/SystemUpdate.vala index baf302a8..98c80bb2 100644 --- a/src/Backends/SystemUpdate.vala +++ b/src/Backends/SystemUpdate.vala @@ -7,20 +7,6 @@ [DBus (name="io.elementary.settings_daemon.SystemUpdate")] public class SettingsDaemon.Backends.SystemUpdate : Object { - public enum State { - UP_TO_DATE, - CHECKING, - AVAILABLE, - DOWNLOADING, - RESTART_REQUIRED, - ERROR - } - - public struct CurrentState { - State state; - string status; - } - public struct UpdateDetails { string[] packages; int size; @@ -33,7 +19,7 @@ public class SettingsDaemon.Backends.SystemUpdate : Object { private static Settings settings = new GLib.Settings ("io.elementary.settings-daemon.system-update"); - private CurrentState current_state; + private PkUtils.CurrentState current_state; private UpdateDetails update_details; private Pk.Task task; @@ -202,7 +188,7 @@ public class SettingsDaemon.Backends.SystemUpdate : Object { update_state (ERROR, message); } - private void update_state (State state, string message = "") { + private void update_state (PkUtils.State state, string message = "") { current_state = { state, message @@ -211,7 +197,7 @@ public class SettingsDaemon.Backends.SystemUpdate : Object { state_changed (); } - public async CurrentState get_current_state () throws DBusError, IOError { + public async PkUtils.CurrentState get_current_state () throws DBusError, IOError { return current_state; } diff --git a/src/Backends/UbuntuDrivers.vala b/src/Backends/UbuntuDrivers.vala index 59ff71d9..8740015c 100644 --- a/src/Backends/UbuntuDrivers.vala +++ b/src/Backends/UbuntuDrivers.vala @@ -7,25 +7,11 @@ [DBus (name="io.elementary.settings_daemon.Drivers")] public class SettingsDaemon.Backends.UbuntuDrivers : Object { - public enum State { - UP_TO_DATE, - CHECKING, - AVAILABLE, - DOWNLOADING, - RESTART_REQUIRED, - ERROR - } - - public struct CurrentState { - State state; - string status; - } - private const string NOTIFICATION_ID = "drivers"; public signal void state_changed (); - private CurrentState current_state; + private PkUtils.CurrentState current_state; private HashTable> available_drivers; private Pk.Task task; @@ -179,7 +165,7 @@ public class SettingsDaemon.Backends.UbuntuDrivers : Object { update_state (ERROR, message); } - private void update_state (State state, string message = "") { + private void update_state (PkUtils.State state, string message = "") { current_state = { state, message @@ -188,7 +174,7 @@ public class SettingsDaemon.Backends.UbuntuDrivers : Object { state_changed (); } - public async CurrentState get_current_state () throws DBusError, IOError { + public async PkUtils.CurrentState get_current_state () throws DBusError, IOError { return current_state; } diff --git a/src/Utils/PkUtils.vala b/src/Utils/PkUtils.vala index 69362690..3599fb02 100644 --- a/src/Utils/PkUtils.vala +++ b/src/Utils/PkUtils.vala @@ -1,4 +1,18 @@ namespace SettingsDaemon.PkUtils { + public enum State { + UP_TO_DATE, + CHECKING, + AVAILABLE, + DOWNLOADING, + RESTART_REQUIRED, + ERROR + } + + public struct CurrentState { + State state; + string status; + } + public static unowned string status_to_title (Pk.Status status) { // From https://github.com/elementary/appcenter/blob/master/src/Core/ChangeInformation.vala#L51 switch (status) { From 16a616efd6f0447e53c3e5188b6384f822d32660 Mon Sep 17 00:00:00 2001 From: Leonhard Date: Wed, 7 Feb 2024 20:34:03 +0100 Subject: [PATCH 04/19] Lint --- src/Utils/PkUtils.vala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Utils/PkUtils.vala b/src/Utils/PkUtils.vala index 3599fb02..c6e23e71 100644 --- a/src/Utils/PkUtils.vala +++ b/src/Utils/PkUtils.vala @@ -89,4 +89,4 @@ namespace SettingsDaemon.PkUtils { return _("Installing"); } } -} \ No newline at end of file +} From 0bdce07196749dca329d566d277e41ef0ebef3fb Mon Sep 17 00:00:00 2001 From: Leonhard Date: Wed, 7 Feb 2024 20:40:24 +0100 Subject: [PATCH 05/19] Install all packages that belong to a driver --- src/Backends/UbuntuDrivers.vala | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/Backends/UbuntuDrivers.vala b/src/Backends/UbuntuDrivers.vala index 8740015c..e8d1bd09 100644 --- a/src/Backends/UbuntuDrivers.vala +++ b/src/Backends/UbuntuDrivers.vala @@ -117,13 +117,16 @@ public class SettingsDaemon.Backends.UbuntuDrivers : Object { } } - public async void install (string pkg_name) throws DBusError, IOError { + public async void install (string pkg_id) throws DBusError, IOError { cancellable.reset (); update_state (DOWNLOADING); + string[] package_names = {}; + available_drivers[pkg_id].@foreach ((package_name) => package_names += package_name); + try { - var results = yield task.install_packages_async ({ pkg_name }, cancellable, progress_callback); + var results = yield task.install_packages_async (package_names, cancellable, progress_callback); if (results.get_exit_code () == CANCELLED) { debug ("Installation was cancelled"); From a49b919be0b5124340041d9ef862046338a43aeb Mon Sep 17 00:00:00 2001 From: Leonhard Date: Sat, 10 Feb 2024 17:25:41 +0100 Subject: [PATCH 06/19] WIP --- src/Backends/UbuntuDrivers.vala | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Backends/UbuntuDrivers.vala b/src/Backends/UbuntuDrivers.vala index e8d1bd09..77b0a267 100644 --- a/src/Backends/UbuntuDrivers.vala +++ b/src/Backends/UbuntuDrivers.vala @@ -46,6 +46,7 @@ public class SettingsDaemon.Backends.UbuntuDrivers : Object { command = new Subprocess (SubprocessFlags.STDOUT_PIPE, drivers_exec_path, "list"); yield command.communicate_utf8_async (null, cancellable, out output, null); } catch (Error e) { + critical ("Failed to launch ubuntu-drivers: %s", e.message); return false; } @@ -64,6 +65,7 @@ public class SettingsDaemon.Backends.UbuntuDrivers : Object { var result = yield get_drivers_output (cancellable, out command_output); if (!result || command_output == null) { update_state (UP_TO_DATE); + critical ("Failed to get ubuntu-drivers output"); return; } From 1c1a16bdd93131c2a41461175aefafa51e345721 Mon Sep 17 00:00:00 2001 From: Leonhard Date: Sat, 17 Feb 2024 21:51:51 +0100 Subject: [PATCH 07/19] Add installed information, find package ids --- src/Backends/UbuntuDrivers.vala | 69 +++++++++++++++++++++++++++++---- 1 file changed, 61 insertions(+), 8 deletions(-) diff --git a/src/Backends/UbuntuDrivers.vala b/src/Backends/UbuntuDrivers.vala index 77b0a267..b6c4c6e9 100644 --- a/src/Backends/UbuntuDrivers.vala +++ b/src/Backends/UbuntuDrivers.vala @@ -12,7 +12,8 @@ public class SettingsDaemon.Backends.UbuntuDrivers : Object { public signal void state_changed (); private PkUtils.CurrentState current_state; - private HashTable> available_drivers; + private HashTable> available_drivers; + private HashTable available_drivers_with_installed; private Pk.Task task; private GLib.Cancellable cancellable; @@ -23,7 +24,8 @@ public class SettingsDaemon.Backends.UbuntuDrivers : Object { "" }; - available_drivers = new HashTable> (str_hash, str_equal); + available_drivers = new HashTable> (str_hash, str_equal); + available_drivers_with_installed = new HashTable (str_hash, str_equal); task = new Pk.Task () { only_download = true @@ -75,6 +77,11 @@ public class SettingsDaemon.Backends.UbuntuDrivers : Object { continue; } + // Filter out the nvidia server drivers + if (package_name.contains ("nvidia") && package_name.contains ("-server")) { + continue; + } + // ubuntu-drivers returns lines like the following for dkms packages: // backport-iwlwifi-dkms, (kernel modules provided by backport-iwlwifi-dkms) // nvidia-driver-470, (kernel modules provided by linux-modules-nvidia-470-generic-hwe-20.04) @@ -82,8 +89,8 @@ public class SettingsDaemon.Backends.UbuntuDrivers : Object { string[] parts = package_name.split (","); // Get the driver part (before the comma) - var package_names = new GenericSet (str_hash, str_equal); - package_names.add (parts[0]); + string[] package_names = {}; + package_names += parts[0]; if (parts.length > 1) { if (parts[1].contains ("kernel modules provided by")) { @@ -93,13 +100,18 @@ public class SettingsDaemon.Backends.UbuntuDrivers : Object { // Strip off the trailing bracket last_part = last_part.replace (")", ""); - package_names.add (last_part); + if (!(last_part in package_names)) { + package_names += last_part; + } } else { warning ("Unrecognised line from ubuntu-drivers, needs checking: %s", package_name); } } - available_drivers[package_name] = package_names; + var package_ids = yield get_pkgs_ids (package_names); + + available_drivers[parts[0]] = package_ids; + available_drivers_with_installed[parts[0]] = check_installed (package_ids.data); } if (available_drivers.length == 0) { @@ -119,7 +131,48 @@ public class SettingsDaemon.Backends.UbuntuDrivers : Object { } } + private async GenericArray get_pkgs_ids (string[] package_names) { + var array = new GenericArray (); + try { + var result = yield task.resolve_async (Pk.Filter.NONE, package_names, null, () => {}); + + var packages = result.get_package_array (); + foreach (var package in packages) { + array.add (package.package_id); + } + } catch (Error e) { + critical ("Failed to get package details, treating as not installed: %s", e.message); + } + + return array; + } + + private bool check_installed (string[] pkg_ids) { + var sack = new Pk.PackageSack (); + foreach (var id in pkg_ids) { + try { + sack.add_package_by_id (id); + } catch (Error e) { + critical ("Failed to add package %s, treating as not installed: %s", id, e.message); + return false; + } + } + + foreach (var package in sack.get_array ()) { + if (!(INSTALLED in package.info)) { + return false; + } + } + + return true; + } + public async void install (string pkg_id) throws DBusError, IOError { + if (current_state.state != AVAILABLE) { + warning ("No drivers available, or already downloading a driver."); + return; + } + cancellable.reset (); update_state (DOWNLOADING); @@ -183,7 +236,7 @@ public class SettingsDaemon.Backends.UbuntuDrivers : Object { return current_state; } - public async string[] get_available_drivers () throws DBusError, IOError { - return available_drivers.get_keys_as_array (); + public async HashTable get_available_drivers () throws DBusError, IOError { + return available_drivers_with_installed; } } From 0f5b9682dd6649921917c78ba25cd84ca346457a Mon Sep 17 00:00:00 2001 From: Leonhard Date: Sat, 17 Feb 2024 21:55:36 +0100 Subject: [PATCH 08/19] Various improvements --- src/Backends/UbuntuDrivers.vala | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/Backends/UbuntuDrivers.vala b/src/Backends/UbuntuDrivers.vala index b6c4c6e9..3d073b32 100644 --- a/src/Backends/UbuntuDrivers.vala +++ b/src/Backends/UbuntuDrivers.vala @@ -167,7 +167,7 @@ public class SettingsDaemon.Backends.UbuntuDrivers : Object { return true; } - public async void install (string pkg_id) throws DBusError, IOError { + public async void install (string pkg_name) throws DBusError, IOError { if (current_state.state != AVAILABLE) { warning ("No drivers available, or already downloading a driver."); return; @@ -177,17 +177,16 @@ public class SettingsDaemon.Backends.UbuntuDrivers : Object { update_state (DOWNLOADING); - string[] package_names = {}; - available_drivers[pkg_id].@foreach ((package_name) => package_names += package_name); - try { - var results = yield task.install_packages_async (package_names, cancellable, progress_callback); + var results = yield task.install_packages_async ((owned) available_drivers[pkg_name].data, cancellable, progress_callback); if (results.get_exit_code () == CANCELLED) { debug ("Installation was cancelled"); return; } + available_drivers_with_installed[pkg_name] = true; + Pk.offline_trigger (REBOOT); var notification = new Notification (_("Restart required")); From 1aa99421c0e3fee19e9c81fb2bec1b99cd8754a9 Mon Sep 17 00:00:00 2001 From: Leonhard Date: Sat, 17 Feb 2024 22:11:14 +0100 Subject: [PATCH 09/19] Fix crash on installing a driver --- src/Backends/UbuntuDrivers.vala | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Backends/UbuntuDrivers.vala b/src/Backends/UbuntuDrivers.vala index 3d073b32..0a23cfd0 100644 --- a/src/Backends/UbuntuDrivers.vala +++ b/src/Backends/UbuntuDrivers.vala @@ -178,7 +178,8 @@ public class SettingsDaemon.Backends.UbuntuDrivers : Object { update_state (DOWNLOADING); try { - var results = yield task.install_packages_async ((owned) available_drivers[pkg_name].data, cancellable, progress_callback); + string[] pkgs = available_drivers[pkg_name].data; // It seems arrays are imediately freed with async methods so this prevents a seg fault + var results = yield task.install_packages_async (pkgs, cancellable, progress_callback); if (results.get_exit_code () == CANCELLED) { debug ("Installation was cancelled"); From bbae0292302a67296fb28bf35b205782e7e1e334 Mon Sep 17 00:00:00 2001 From: Leonhard Date: Sat, 17 Feb 2024 22:55:18 +0100 Subject: [PATCH 10/19] Fix installing --- src/Backends/UbuntuDrivers.vala | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/Backends/UbuntuDrivers.vala b/src/Backends/UbuntuDrivers.vala index 0a23cfd0..b62f3763 100644 --- a/src/Backends/UbuntuDrivers.vala +++ b/src/Backends/UbuntuDrivers.vala @@ -27,9 +27,7 @@ public class SettingsDaemon.Backends.UbuntuDrivers : Object { available_drivers = new HashTable> (str_hash, str_equal); available_drivers_with_installed = new HashTable (str_hash, str_equal); - task = new Pk.Task () { - only_download = true - }; + task = new Pk.Task (); cancellable = new GLib.Cancellable (); @@ -188,8 +186,6 @@ public class SettingsDaemon.Backends.UbuntuDrivers : Object { available_drivers_with_installed[pkg_name] = true; - Pk.offline_trigger (REBOOT); - var notification = new Notification (_("Restart required")); notification.set_body (_("Please restart your system to finalize driver installation")); notification.set_icon (new ThemedIcon ("system-reboot")); From 32c0e19f5b84b7c12ceb01c6e244d0999653f901 Mon Sep 17 00:00:00 2001 From: Leonhard Date: Sat, 17 Feb 2024 23:19:51 +0100 Subject: [PATCH 11/19] Make installed detection work --- src/Backends/UbuntuDrivers.vala | 31 +++++-------------------------- 1 file changed, 5 insertions(+), 26 deletions(-) diff --git a/src/Backends/UbuntuDrivers.vala b/src/Backends/UbuntuDrivers.vala index b62f3763..0b7c142e 100644 --- a/src/Backends/UbuntuDrivers.vala +++ b/src/Backends/UbuntuDrivers.vala @@ -106,10 +106,7 @@ public class SettingsDaemon.Backends.UbuntuDrivers : Object { } } - var package_ids = yield get_pkgs_ids (package_names); - - available_drivers[parts[0]] = package_ids; - available_drivers_with_installed[parts[0]] = check_installed (package_ids.data); + available_drivers[parts[0]] = yield update_installed (package_names); } if (available_drivers.length == 0) { @@ -129,7 +126,7 @@ public class SettingsDaemon.Backends.UbuntuDrivers : Object { } } - private async GenericArray get_pkgs_ids (string[] package_names) { + private async GenericArray update_installed (string[] package_names) { var array = new GenericArray (); try { var result = yield task.resolve_async (Pk.Filter.NONE, package_names, null, () => {}); @@ -137,6 +134,7 @@ public class SettingsDaemon.Backends.UbuntuDrivers : Object { var packages = result.get_package_array (); foreach (var package in packages) { array.add (package.package_id); + available_drivers_with_installed[package_names[0]] = (Pk.Info.INSTALLED == package.info); } } catch (Error e) { critical ("Failed to get package details, treating as not installed: %s", e.message); @@ -145,26 +143,6 @@ public class SettingsDaemon.Backends.UbuntuDrivers : Object { return array; } - private bool check_installed (string[] pkg_ids) { - var sack = new Pk.PackageSack (); - foreach (var id in pkg_ids) { - try { - sack.add_package_by_id (id); - } catch (Error e) { - critical ("Failed to add package %s, treating as not installed: %s", id, e.message); - return false; - } - } - - foreach (var package in sack.get_array ()) { - if (!(INSTALLED in package.info)) { - return false; - } - } - - return true; - } - public async void install (string pkg_name) throws DBusError, IOError { if (current_state.state != AVAILABLE) { warning ("No drivers available, or already downloading a driver."); @@ -181,10 +159,11 @@ public class SettingsDaemon.Backends.UbuntuDrivers : Object { if (results.get_exit_code () == CANCELLED) { debug ("Installation was cancelled"); + update_state (AVAILABLE); return; } - available_drivers_with_installed[pkg_name] = true; + yield check_for_drivers (false); var notification = new Notification (_("Restart required")); notification.set_body (_("Please restart your system to finalize driver installation")); From 9377eff712f2ae897e2d6be15c8a9f83e55a575b Mon Sep 17 00:00:00 2001 From: Leonhard Date: Sun, 18 Feb 2024 00:43:18 +0100 Subject: [PATCH 12/19] Add check --- src/Backends/UbuntuDrivers.vala | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/Backends/UbuntuDrivers.vala b/src/Backends/UbuntuDrivers.vala index 0b7c142e..e7e8968a 100644 --- a/src/Backends/UbuntuDrivers.vala +++ b/src/Backends/UbuntuDrivers.vala @@ -143,7 +143,13 @@ public class SettingsDaemon.Backends.UbuntuDrivers : Object { return array; } + // TODO: Add queue public async void install (string pkg_name) throws DBusError, IOError { + if (!(pkg_name in available_drivers)) { + critical ("Driver not found"); + return; + } + if (current_state.state != AVAILABLE) { warning ("No drivers available, or already downloading a driver."); return; From b85f309a6b94d96ff71c7c3d5f38b05e693d9fcc Mon Sep 17 00:00:00 2001 From: Leonhard Date: Sun, 18 Feb 2024 01:07:10 +0100 Subject: [PATCH 13/19] It actually worksio.elementary.settings-daemon ! --- src/Backends/UbuntuDrivers.vala | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/src/Backends/UbuntuDrivers.vala b/src/Backends/UbuntuDrivers.vala index e7e8968a..34cab04d 100644 --- a/src/Backends/UbuntuDrivers.vala +++ b/src/Backends/UbuntuDrivers.vala @@ -106,7 +106,7 @@ public class SettingsDaemon.Backends.UbuntuDrivers : Object { } } - available_drivers[parts[0]] = yield update_installed (package_names); + available_drivers[parts[0]] = yield update_installed (parts[0], package_names); } if (available_drivers.length == 0) { @@ -126,15 +126,23 @@ public class SettingsDaemon.Backends.UbuntuDrivers : Object { } } - private async GenericArray update_installed (string[] package_names) { + private async GenericArray update_installed (string driver, string[] package_names) { var array = new GenericArray (); try { var result = yield task.resolve_async (Pk.Filter.NONE, package_names, null, () => {}); var packages = result.get_package_array (); + + bool all_installed = true; foreach (var package in packages) { array.add (package.package_id); - available_drivers_with_installed[package_names[0]] = (Pk.Info.INSTALLED == package.info); + + if (all_installed && (Pk.Info.INSTALLED == package.info)) { + available_drivers_with_installed[driver] = true; + } else { + all_installed = false; + available_drivers_with_installed[driver] = false; + } } } catch (Error e) { critical ("Failed to get package details, treating as not installed: %s", e.message); @@ -169,7 +177,10 @@ public class SettingsDaemon.Backends.UbuntuDrivers : Object { return; } - yield check_for_drivers (false); + foreach (var driver in available_drivers.get_keys ()) { + string[] driver_pkgs = available_drivers[driver].data; + yield update_installed (driver, driver_pkgs); + } var notification = new Notification (_("Restart required")); notification.set_body (_("Please restart your system to finalize driver installation")); @@ -178,7 +189,7 @@ public class SettingsDaemon.Backends.UbuntuDrivers : Object { GLib.Application.get_default ().send_notification (NOTIFICATION_ID, notification); - update_state (RESTART_REQUIRED); + update_state (AVAILABLE); } catch (Error e) { critical ("Failed to install driver: %s", e.message); send_error (e.message); From fba324ffe0c785645f5d17f826af8cdcd9bacd66 Mon Sep 17 00:00:00 2001 From: Leonhard Date: Sun, 18 Feb 2024 01:23:12 +0100 Subject: [PATCH 14/19] Remove state check on checking --- src/Backends/UbuntuDrivers.vala | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/Backends/UbuntuDrivers.vala b/src/Backends/UbuntuDrivers.vala index 34cab04d..0efb520c 100644 --- a/src/Backends/UbuntuDrivers.vala +++ b/src/Backends/UbuntuDrivers.vala @@ -54,10 +54,6 @@ public class SettingsDaemon.Backends.UbuntuDrivers : Object { } public async void check_for_drivers (bool notify) throws DBusError, IOError { - if (current_state.state != UP_TO_DATE && current_state.state != AVAILABLE) { - return; - } - update_state (CHECKING); available_drivers.remove_all (); From ca998bc1e54a06c5df0cebd93068337f7496a54c Mon Sep 17 00:00:00 2001 From: Leonhard Date: Sun, 18 Feb 2024 02:04:57 +0100 Subject: [PATCH 15/19] Cleanup --- src/Backends/SystemUpdate.vala | 1 - src/Backends/UbuntuDrivers.vala | 1 - 2 files changed, 2 deletions(-) diff --git a/src/Backends/SystemUpdate.vala b/src/Backends/SystemUpdate.vala index 98c80bb2..674dc14b 100644 --- a/src/Backends/SystemUpdate.vala +++ b/src/Backends/SystemUpdate.vala @@ -72,7 +72,6 @@ public class SettingsDaemon.Backends.SystemUpdate : Object { update_state (CHECKING); try { - //TODO: maybe check for prepared packages with Pk.offline_get_prepared_ids because it seems refreshing cache deletes prepared packages (which should only be a problem with drivers but still) yield task.refresh_cache_async (force, null, progress_callback); } catch (Error e) { warning ("Failed to refresh cache: %s", e.message); diff --git a/src/Backends/UbuntuDrivers.vala b/src/Backends/UbuntuDrivers.vala index 0efb520c..b96efdbb 100644 --- a/src/Backends/UbuntuDrivers.vala +++ b/src/Backends/UbuntuDrivers.vala @@ -147,7 +147,6 @@ public class SettingsDaemon.Backends.UbuntuDrivers : Object { return array; } - // TODO: Add queue public async void install (string pkg_name) throws DBusError, IOError { if (!(pkg_name in available_drivers)) { critical ("Driver not found"); From 16fddeafd33d75068f9de2ff58514e25faefbc53 Mon Sep 17 00:00:00 2001 From: Leonhard Date: Sun, 18 Feb 2024 22:48:30 +0100 Subject: [PATCH 16/19] Add first parsing prototype --- src/Backends/UbuntuDrivers.vala | 71 +++++++++++++++++++++++++++++---- 1 file changed, 64 insertions(+), 7 deletions(-) diff --git a/src/Backends/UbuntuDrivers.vala b/src/Backends/UbuntuDrivers.vala index b96efdbb..d849eb28 100644 --- a/src/Backends/UbuntuDrivers.vala +++ b/src/Backends/UbuntuDrivers.vala @@ -9,11 +9,18 @@ public class SettingsDaemon.Backends.UbuntuDrivers : Object { private const string NOTIFICATION_ID = "drivers"; + private class Device : Object { + public string name; + public HashTable available_drivers_with_installed = new HashTable (str_hash, str_equal); + } + public signal void state_changed (); private PkUtils.CurrentState current_state; private HashTable> available_drivers; private HashTable available_drivers_with_installed; + private HashTable devices_by_drivers; + private Device[] devices = {}; private Pk.Task task; private GLib.Cancellable cancellable; @@ -26,6 +33,7 @@ public class SettingsDaemon.Backends.UbuntuDrivers : Object { available_drivers = new HashTable> (str_hash, str_equal); available_drivers_with_installed = new HashTable (str_hash, str_equal); + devices_by_drivers = new HashTable (str_hash, str_equal); task = new Pk.Task (); @@ -34,7 +42,7 @@ public class SettingsDaemon.Backends.UbuntuDrivers : Object { check_for_drivers.begin (true); } - private async bool get_drivers_output (Cancellable? cancellable = null, out string? output = null) { + private async bool get_drivers_output (string verb, out string? output = null) { output = null; string? drivers_exec_path = Environment.find_program_in_path ("ubuntu-drivers"); if (drivers_exec_path == null) { @@ -43,7 +51,7 @@ public class SettingsDaemon.Backends.UbuntuDrivers : Object { Subprocess command; try { - command = new Subprocess (SubprocessFlags.STDOUT_PIPE, drivers_exec_path, "list"); + command = new Subprocess (SubprocessFlags.STDOUT_PIPE, drivers_exec_path, verb); yield command.communicate_utf8_async (null, cancellable, out output, null); } catch (Error e) { critical ("Failed to launch ubuntu-drivers: %s", e.message); @@ -53,12 +61,53 @@ public class SettingsDaemon.Backends.UbuntuDrivers : Object { return command.get_exit_status () == 0; } + private async void check_devices () { + string? command_output; + var result = yield get_drivers_output ("devices", out command_output); + if (!result || command_output == null) { + update_state (UP_TO_DATE); + critical ("Failed to get ubuntu-drivers output"); + return; + } + + string[] tokens = command_output.split ("\n"); + Device? current_device = null; + foreach (var token in tokens) { + if ("==" in token) { + current_device = new Device (); + devices += current_device; + continue; + } + + if (current_device == null) { + continue; + } + + if (token.has_prefix ("model")) { + var normalized_token = token.splice (0, 10); + current_device.name = normalized_token; + continue; + } + + if (token.has_prefix ("driver")) { + var normalized_token = token.splice (0, 10); + var split_token = normalized_token.split (" - "); + var driver = split_token[0]; + devices_by_drivers[driver] = current_device; + continue; + } + } + } + public async void check_for_drivers (bool notify) throws DBusError, IOError { update_state (CHECKING); + available_drivers.remove_all (); + yield check_devices (); + string? command_output; - var result = yield get_drivers_output (cancellable, out command_output); + var result = yield get_drivers_output ("list", out command_output); if (!result || command_output == null) { update_state (UP_TO_DATE); critical ("Failed to get ubuntu-drivers output"); @@ -133,11 +182,15 @@ public class SettingsDaemon.Backends.UbuntuDrivers : Object { foreach (var package in packages) { array.add (package.package_id); + if (!(driver in devices_by_drivers)) { + continue; + } + if (all_installed && (Pk.Info.INSTALLED == package.info)) { - available_drivers_with_installed[driver] = true; + devices_by_drivers[driver].available_drivers_with_installed[driver] = true; } else { all_installed = false; - available_drivers_with_installed[driver] = false; + devices_by_drivers[driver].available_drivers_with_installed[driver] = false; } } } catch (Error e) { @@ -223,7 +276,11 @@ public class SettingsDaemon.Backends.UbuntuDrivers : Object { return current_state; } - public async HashTable get_available_drivers () throws DBusError, IOError { - return available_drivers_with_installed; + public async HashTable> get_available_drivers () throws DBusError, IOError { + var map = new HashTable> (str_hash, str_equal); + foreach (var device in devices) { + map[device.name] = device.available_drivers_with_installed; + } + return map; } } From c3e67592f79523cc62889dda7fdbb14bd2aa9e75 Mon Sep 17 00:00:00 2001 From: Leonhard Date: Sun, 18 Feb 2024 22:55:40 +0100 Subject: [PATCH 17/19] Make it work --- src/Backends/UbuntuDrivers.vala | 56 ++++++++++++++++++--------------- 1 file changed, 31 insertions(+), 25 deletions(-) diff --git a/src/Backends/UbuntuDrivers.vala b/src/Backends/UbuntuDrivers.vala index d849eb28..85ffd064 100644 --- a/src/Backends/UbuntuDrivers.vala +++ b/src/Backends/UbuntuDrivers.vala @@ -18,7 +18,6 @@ public class SettingsDaemon.Backends.UbuntuDrivers : Object { private PkUtils.CurrentState current_state; private HashTable> available_drivers; - private HashTable available_drivers_with_installed; private HashTable devices_by_drivers; private Device[] devices = {}; @@ -32,7 +31,6 @@ public class SettingsDaemon.Backends.UbuntuDrivers : Object { }; available_drivers = new HashTable> (str_hash, str_equal); - available_drivers_with_installed = new HashTable (str_hash, str_equal); devices_by_drivers = new HashTable (str_hash, str_equal); task = new Pk.Task (); @@ -42,35 +40,34 @@ public class SettingsDaemon.Backends.UbuntuDrivers : Object { check_for_drivers.begin (true); } - private async bool get_drivers_output (string verb, out string? output = null) { - output = null; + private async string? get_drivers_output (string verb) { string? drivers_exec_path = Environment.find_program_in_path ("ubuntu-drivers"); if (drivers_exec_path == null) { - return false; + return null; } - Subprocess command; try { - command = new Subprocess (SubprocessFlags.STDOUT_PIPE, drivers_exec_path, verb); + var command = new Subprocess (SubprocessFlags.STDOUT_PIPE, drivers_exec_path, verb); + + string output; yield command.communicate_utf8_async (null, cancellable, out output, null); + + return output; } catch (Error e) { critical ("Failed to launch ubuntu-drivers: %s", e.message); - return false; + return null; } - - return command.get_exit_status () == 0; } private async void check_devices () { - string? command_output; - var result = yield get_drivers_output ("devices", out command_output); - if (!result || command_output == null) { - update_state (UP_TO_DATE); + var output = yield get_drivers_output ("devices"); + if (output == null) { critical ("Failed to get ubuntu-drivers output"); return; } - string[] tokens = command_output.split ("\n"); + string[] tokens = output.split ("\n"); + Device? current_device = null; foreach (var token in tokens) { if ("==" in token) { @@ -106,22 +103,21 @@ public class SettingsDaemon.Backends.UbuntuDrivers : Object { yield check_devices (); - string? command_output; - var result = yield get_drivers_output ("list", out command_output); - if (!result || command_output == null) { + var command_output = yield get_drivers_output ("list"); + if (command_output == null) { update_state (UP_TO_DATE); critical ("Failed to get ubuntu-drivers output"); return; } string[] tokens = command_output.split ("\n"); - foreach (unowned string package_name in tokens) { - if (package_name.strip () == "") { + foreach (unowned string line in tokens) { + if (line.strip () == "") { continue; } // Filter out the nvidia server drivers - if (package_name.contains ("nvidia") && package_name.contains ("-server")) { + if (line.contains ("nvidia") && line.contains ("-server")) { continue; } @@ -130,10 +126,18 @@ public class SettingsDaemon.Backends.UbuntuDrivers : Object { // nvidia-driver-470, (kernel modules provided by linux-modules-nvidia-470-generic-hwe-20.04) // we want to install both packages if they're different - string[] parts = package_name.split (","); + string[] parts = line.split (","); + + var driver = parts[0]; + + if (driver == null || !(driver in devices_by_drivers)) { + continue; + } + // Get the driver part (before the comma) string[] package_names = {}; - package_names += parts[0]; + + package_names += driver; if (parts.length > 1) { if (parts[1].contains ("kernel modules provided by")) { @@ -147,11 +151,11 @@ public class SettingsDaemon.Backends.UbuntuDrivers : Object { package_names += last_part; } } else { - warning ("Unrecognised line from ubuntu-drivers, needs checking: %s", package_name); + warning ("Unrecognised line from ubuntu-drivers, needs checking: %s", line); } } - available_drivers[parts[0]] = yield update_installed (parts[0], package_names); + available_drivers[driver] = yield update_installed (driver, package_names); } if (available_drivers.length == 0) { @@ -278,9 +282,11 @@ public class SettingsDaemon.Backends.UbuntuDrivers : Object { public async HashTable> get_available_drivers () throws DBusError, IOError { var map = new HashTable> (str_hash, str_equal); + foreach (var device in devices) { map[device.name] = device.available_drivers_with_installed; } + return map; } } From 39c63d44045ae9dec7564f8abf4e98218e49c163 Mon Sep 17 00:00:00 2001 From: Leonhard Date: Sun, 18 Feb 2024 23:03:04 +0100 Subject: [PATCH 18/19] Fix splicing --- src/Backends/UbuntuDrivers.vala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Backends/UbuntuDrivers.vala b/src/Backends/UbuntuDrivers.vala index 85ffd064..a94f70db 100644 --- a/src/Backends/UbuntuDrivers.vala +++ b/src/Backends/UbuntuDrivers.vala @@ -81,13 +81,13 @@ public class SettingsDaemon.Backends.UbuntuDrivers : Object { } if (token.has_prefix ("model")) { - var normalized_token = token.splice (0, 10); + var normalized_token = token.splice (0, 11); current_device.name = normalized_token; continue; } if (token.has_prefix ("driver")) { - var normalized_token = token.splice (0, 10); + var normalized_token = token.splice (0, 11); var split_token = normalized_token.split (" - "); var driver = split_token[0]; devices_by_drivers[driver] = current_device; From 895c4a71e8eec6df8af90d608ff849d95b0c5a6b Mon Sep 17 00:00:00 2001 From: Leonhard Date: Wed, 15 May 2024 22:51:32 +0200 Subject: [PATCH 19/19] Add meson option --- meson_options.txt | 1 + src/Application.vala | 3 +++ src/meson.build | 9 ++++++++- 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/meson_options.txt b/meson_options.txt index f7cf46d2..2689e2e3 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -1,3 +1,4 @@ option('busctlpath', type: 'string', value: '', description: 'custom path to busctl executable') +option('ubuntu_drivers', type: 'boolean', value: 'true', description: 'whether to enable ubuntu drivers integration') option('systemdsystemunitdir', type: 'string', value: '', description: 'custom directory for systemd system units, or \'no\' to disable') option('systemduserunitdir', type: 'string', value: '', description: 'custom directory for systemd user units, or \'no\' to disable') diff --git a/src/Application.vala b/src/Application.vala index ebf7b212..31322ee4 100644 --- a/src/Application.vala +++ b/src/Application.vala @@ -79,7 +79,10 @@ public sealed class SettingsDaemon.Application : Gtk.Application { base.dbus_register (connection, object_path); connection.register_object (object_path, new Backends.SystemUpdate ()); + +#if UBUNTU_DRIVERS connection.register_object (object_path, new Backends.UbuntuDrivers ()); +#endif return true; } diff --git a/src/meson.build b/src/meson.build index 105bd0eb..eda9764c 100644 --- a/src/meson.build +++ b/src/meson.build @@ -10,11 +10,17 @@ sources = files( 'Backends/PowerProfilesSync.vala', 'Backends/PrefersColorSchemeSettings.vala', 'Backends/SystemUpdate.vala', - 'Backends/UbuntuDrivers.vala', 'Utils/PkUtils.vala', 'Utils/SunriseSunsetCalculator.vala', ) +args = [] + +if get_option('ubuntu_drivers') + sources += files('Backends/UbuntuDrivers.vala') + args += '--define=UBUNTU_DRIVERS' +endif + executable( meson.project_name(), sources, @@ -30,5 +36,6 @@ executable( m_dep, pk_dep ], + vala_args: args, install: true, )