diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 34e79186..7e87ae80 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -25,7 +25,7 @@ jobs: - name: Install Dependencies run: | apt update - apt install -y libaccountsservice-dev libdbus-1-dev libgranite-dev libgeoclue-2-dev meson valac + apt install -y libaccountsservice-dev libdbus-1-dev libgranite-dev libgeoclue-2-dev libfwupd-dev meson valac - name: Build env: DESTDIR: out diff --git a/README.md b/README.md index 8a009da2..c3e552b1 100644 --- a/README.md +++ b/README.md @@ -7,8 +7,9 @@ You'll need the following dependencies: * gobject-2.0 * libaccountsservice-dev * libdbus-1-dev -* libgranite-dev +* libfwupd-dev * libgeoclue-2-dev +* libgranite-dev * meson * valac diff --git a/data/autostart.desktop b/data/autostart.desktop index 0d8633fa..ef712fc7 100644 --- a/data/autostart.desktop +++ b/data/autostart.desktop @@ -3,6 +3,7 @@ Type=Application Name=Elementary Settings Daemon Comment=Elementary Settings Daemon Exec=io.elementary.settings-daemon +Icon=io.elementary.settings-daemon Terminal=false Categories=System;Core; NoDisplay=true diff --git a/data/icons/128.svg b/data/icons/128.svg new file mode 100644 index 00000000..71c5cc66 --- /dev/null +++ b/data/icons/128.svg @@ -0,0 +1,349 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/data/icons/24.svg b/data/icons/24.svg new file mode 100644 index 00000000..a70ef4d3 --- /dev/null +++ b/data/icons/24.svg @@ -0,0 +1,297 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + diff --git a/data/icons/32.svg b/data/icons/32.svg new file mode 100644 index 00000000..960f517a --- /dev/null +++ b/data/icons/32.svg @@ -0,0 +1,301 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/data/icons/48.svg b/data/icons/48.svg new file mode 100644 index 00000000..46648295 --- /dev/null +++ b/data/icons/48.svg @@ -0,0 +1,481 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/data/icons/64.svg b/data/icons/64.svg new file mode 100644 index 00000000..ec7989aa --- /dev/null +++ b/data/icons/64.svg @@ -0,0 +1,297 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/data/io.elementary.settings-daemon.check-for-firmware-updates.service b/data/io.elementary.settings-daemon.check-for-firmware-updates.service new file mode 100644 index 00000000..5f79b95e --- /dev/null +++ b/data/io.elementary.settings-daemon.check-for-firmware-updates.service @@ -0,0 +1,8 @@ +[Unit] +Description=Check for firmware updates daily +ConditionACPower=true +After=network.target network-online.target systemd-networkd.service NetworkManager.service connman.service + +[Service] +Type=oneshot +ExecStart=/usr/bin/busctl --user call io.elementary.settings-daemon /io/elementary/settings_daemon org.freedesktop.Application ActivateAction sava{sv} "check-firmware-updates" 0 0 diff --git a/data/io.elementary.settings-daemon.check-for-firmware-updates.timer b/data/io.elementary.settings-daemon.check-for-firmware-updates.timer new file mode 100644 index 00000000..43ed38aa --- /dev/null +++ b/data/io.elementary.settings-daemon.check-for-firmware-updates.timer @@ -0,0 +1,9 @@ +[Unit] +Description=Check for firmware updates daily + +[Timer] +OnCalendar=daily +Persistent=true + +[Install] +WantedBy=timers.target diff --git a/data/meson.build b/data/meson.build index 4db0d403..1c59294c 100644 --- a/data/meson.build +++ b/data/meson.build @@ -1,9 +1,15 @@ install_data( 'autostart.desktop', - install_dir: join_paths(get_option('sysconfdir'), 'xdg', 'autostart'), + install_dir: join_paths(get_option('datadir'), 'applications'), rename: meson.project_name() + '.desktop' ) +meson.add_install_script( + symlink, + join_paths(get_option('datadir'), 'applications', meson.project_name() + '.desktop'), + join_paths(get_option('sysconfdir'), 'xdg', 'autostart', meson.project_name() + '.desktop'), +) + dbus_dep = dependency('dbus-1') dbus_interfaces_dir = dbus_dep.get_pkgconfig_variable('interfaces_dir', define_variable: ['datadir', datadir]) @@ -34,3 +40,31 @@ i18n.merge_file( install: true, install_dir: join_paths(get_option('datadir'), 'metainfo'), ) + +systemd = dependency('systemd') +systemd_system_unit_dir = systemd.get_pkgconfig_variable('systemdsystemunitdir') + +install_data( + meson.project_name() + '.check-for-firmware-updates.service', + install_dir: systemd_system_unit_dir +) + +install_data( + meson.project_name() + '.check-for-firmware-updates.timer', + install_dir: systemd_system_unit_dir +) + +icon_sizes = ['24', '32', '48', '64', '128'] + +foreach i : icon_sizes + install_data( + join_paths('icons', i + '.svg'), + install_dir: join_paths(get_option('datadir'), 'icons', 'hicolor', i + 'x' + i, 'apps'), + rename: meson.project_name() + '.svg' + ) + install_data( + join_paths('icons', i + '.svg'), + install_dir: join_paths(get_option('datadir'), 'icons', 'hicolor', i + 'x' + i + '@2', 'apps'), + rename: meson.project_name() + '.svg' + ) +endforeach diff --git a/meson.build b/meson.build index fbf051ad..99b937ac 100644 --- a/meson.build +++ b/meson.build @@ -4,10 +4,17 @@ project('io.elementary.settings-daemon', license: 'GPL3', ) +fwupd_dep = dependency('fwupd') gio_dep = dependency ('gio-2.0') glib_dep = dependency('glib-2.0') granite_dep = dependency('granite', version: '>= 5.3.0') i18n = import('i18n') +gettext_name = meson.project_name() + +add_project_arguments( + '-DGETTEXT_PACKAGE="@0@"'.format(gettext_name), + language:'c' +) cc = meson.get_compiler('c') m_dep = cc.find_library('m', required : false) diff --git a/po/POTFILES b/po/POTFILES index 31a08460..469c9356 100644 --- a/po/POTFILES +++ b/po/POTFILES @@ -1 +1,2 @@ data/settings-daemon.appdata.xml.in +src/Application.vala diff --git a/src/Application.vala b/src/Application.vala index 39c8a5e1..543db2ac 100644 --- a/src/Application.vala +++ b/src/Application.vala @@ -48,6 +48,62 @@ public class SettingsDaemon.Application : GLib.Application { add_main_option_entries (OPTIONS); housekeeping = new Backends.Housekeeping (); + + var check_firmware_updates_action = new SimpleAction ("check-firmware-updates", null); + check_firmware_updates_action.activate.connect (() => { + var fwupd_client = new Fwupd.Client (); + var num_updates = 0; + try { + var devices = fwupd_client.get_devices (); + for (int i = 0; i < devices.length; i++) { + var device = devices[i]; + if (device.has_flag (Fwupd.DEVICE_FLAG_UPDATABLE)) { + Fwupd.Release? release = null; + try { + var upgrades = fwupd_client.get_upgrades (device.get_id ()); + + if (upgrades != null) { + release = upgrades[0]; + } + } catch (Error e) { + warning (e.message); + } + + if (release != null && device.get_version () != release.get_version ()) { + num_updates++; + } + } + } + } catch (Error e) { + warning (e.message); + } + + if (num_updates != 0U) { + string title = ngettext ("Firmware Update Available", "Firmware Updates Available", num_updates); + string body = ngettext ("%u update is available for your hardware", "%u updates are available for your hardware", num_updates).printf (num_updates); + + var notification = new Notification (title); + notification.set_body (body); + notification.set_icon (new ThemedIcon ("application-x-firmware")); + notification.set_default_action ("app.show-firmware-updates"); + + send_notification ("io.elementary.settings-daemon.firmware.updates", notification); + } else { + withdraw_notification ("io.elementary.settings-daemon.firmware.updates"); + } + }); + + var show_firmware_updates_action = new SimpleAction ("show-firmware-updates", null); + show_firmware_updates_action.activate.connect (() => { + try { + Gtk.show_uri_on_window (null, "settings://about/firmware", Gdk.CURRENT_TIME); + } catch (Error e) { + critical (e.message); + } + }); + + add_action (check_firmware_updates_action); + add_action (show_firmware_updates_action); } public override int handle_local_options (VariantDict options) { diff --git a/src/meson.build b/src/meson.build index 7c726d97..a61bb9e6 100644 --- a/src/meson.build +++ b/src/meson.build @@ -14,6 +14,7 @@ executable( sources, dependencies: [ config_dep, + fwupd_dep, gio_dep, glib_dep, granite_dep,