From 13ed252cd610e8d23ff92cc369a9260bc8231d65 Mon Sep 17 00:00:00 2001 From: Marius Meisenzahl Date: Sat, 29 Jan 2022 11:23:34 +0100 Subject: [PATCH 1/9] Add dumb dialog to simulate upgrade flow --- src/Views/OperatingSystemView.vala | 152 +++++++++++++++++++++++++++++ 1 file changed, 152 insertions(+) diff --git a/src/Views/OperatingSystemView.vala b/src/Views/OperatingSystemView.vala index 1d9ac1946..d8c15934d 100644 --- a/src/Views/OperatingSystemView.vala +++ b/src/Views/OperatingSystemView.vala @@ -112,6 +112,14 @@ public class About.OperatingSystemView : Gtk.Grid { margin_top = 12 }; + var upgrade_button = new Gtk.Button.with_label (_("Upgrade system")); + upgrade_button.get_style_context ().add_class (Granite.STYLE_CLASS_ACCENT); + upgrade_button.clicked.connect (show_upgrade_dialog); + + var upgrade_revealer = new Gtk.Revealer (); + upgrade_revealer.add (upgrade_button); + upgrade_revealer.reveal_child = true; + var bug_button = new Gtk.Button.with_label (_("Send Feedback")); Gtk.Button? update_button = null; @@ -131,6 +139,7 @@ public class About.OperatingSystemView : Gtk.Grid { spacing = 6 }; button_grid.add (settings_restore_button); + button_grid.add (upgrade_revealer); button_grid.add (bug_button); if (update_button != null) { button_grid.add (update_button); @@ -301,4 +310,147 @@ public class About.OperatingSystemView : Gtk.Grid { settings.apply (); GLib.Settings.sync (); } + + private const int RESTART_TIMEOUT = 30; + + enum State { + OVERVIEW, + WARNING, + PROGRESS, + SUCCESS, + RESTART + } + + private void show_upgrade_dialog () { + int seconds_remaining = RESTART_TIMEOUT; + + var message_dialog = new Granite.MessageDialog.with_image_from_icon_name ( + "elementary OS Next", + "To setup the installation of elementary OS Next, click Continue.", + "distributor-logo", + Gtk.ButtonsType.CANCEL + ) { + badge_icon = new ThemedIcon ("system-software-update"), + transient_for = (Gtk.Window) get_toplevel (), + modal = true + }; + + 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.ACCEPT); + + var stack = new Gtk.Stack (); + stack.set_transition_type (Gtk.StackTransitionType.SLIDE_LEFT_RIGHT); + + var state = State.OVERVIEW; + + var overview_view = new Gtk.Label (""); + stack.add (overview_view); + + var warning_view = new Gtk.Label ( + "· " + _("Before you upgrade, we recommend that you back up your data") + "\n" + + "· " + _("To prevent data loss close all open applications and documents") + ) { + max_width_chars = 60, + wrap = true, + xalign = 0, + use_markup = true + }; + stack.add (warning_view); + + var progress_view = new Gtk.ProgressBar (); + stack.add (progress_view); + + var success_view = new Gtk.Label ("") { + max_width_chars = 60, + wrap = true, + xalign = 0, + use_markup = true + }; + stack.add (success_view); + + message_dialog.custom_bin.add (stack); + + message_dialog.show_all (); + message_dialog.response.connect ((response_id) => { + if (response_id == Gtk.ResponseType.ACCEPT) { + state = state + 1; + } else if (response_id == Gtk.ResponseType.CANCEL) { + message_dialog.destroy (); + } + + switch (state) { + case State.WARNING: + message_dialog.badge_icon = new ThemedIcon ("dialog-warning"); + message_dialog.secondary_text = _("Make sure you are ready to upgrade."); + suggested_button.label = _("Upgrade"); + stack.set_visible_child (warning_view); + break; + case State.PROGRESS: + message_dialog.badge_icon = new ThemedIcon ("system-software-update"); + message_dialog.secondary_text = _("The upgrade is being prepared. Please do not shut down your device."); + suggested_button.visible = false; + stack.set_visible_child (progress_view); + + progress_view.notify["fraction"].connect (() => { + if (progress_view.fraction >= 1.0) { + suggested_button.activate (); + } + }); + + Timeout.add_seconds (1, () => { + progress_view.fraction += Random.next_double () * 0.1; + + if (progress_view.fraction >= 1.0) { + return Source.REMOVE; + } + + return Source.CONTINUE; + }); + + break; + case State.SUCCESS: + message_dialog.badge_icon = new ThemedIcon ("process-completed"); + message_dialog.secondary_text = _("Upgrade was successfully prepared."); + success_view.label = get_restart_text (seconds_remaining); + suggested_button.label = _("Restart"); + suggested_button.visible = true; + stack.set_visible_child (success_view); + + Timeout.add_seconds (RESTART_TIMEOUT, () => { + suggested_button.activate (); + + return GLib.Source.REMOVE; + }); + + Timeout.add_seconds (1, () => { + seconds_remaining = seconds_remaining - 1; + success_view.label = get_restart_text (seconds_remaining); + + if (seconds_remaining == 0) { + return Source.REMOVE; + } + + return Source.CONTINUE; + }); + + break; + case State.RESTART: + message_dialog.destroy (); + // Utils.restart (); + break; + } + }); + } + + private string get_restart_text (int seconds_remaining) { + return "%s".printf ( + ngettext ( + "Your device will automatically restart in %i second.", + "Your device will automatically restart in %i seconds.", + seconds_remaining + ).printf (seconds_remaining) + " " + + _("Your device may restart more than once during installation.") + ); + } } From 394f2e1b8a99b7ba801076ba4b698d5b63cd0ebb Mon Sep 17 00:00:00 2001 From: Marius Meisenzahl Date: Sat, 29 Jan 2022 11:27:53 +0100 Subject: [PATCH 2/9] Add restart method --- src/Utils/SystemUpgrade.vala | 52 ++++++++++++++++++++++++++++++ src/Views/OperatingSystemView.vala | 2 +- src/meson.build | 1 + 3 files changed, 54 insertions(+), 1 deletion(-) create mode 100644 src/Utils/SystemUpgrade.vala diff --git a/src/Utils/SystemUpgrade.vala b/src/Utils/SystemUpgrade.vala new file mode 100644 index 000000000..b13b38c88 --- /dev/null +++ b/src/Utils/SystemUpgrade.vala @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2022 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.SystemUpgrade { + public static void restart () { + get_system_instance (); + + try { + system_instance.reboot (false); + } catch (GLib.Error e) { + critical (e.message); + } + } + + [DBus (name = "org.freedesktop.login1.Manager")] + interface SystemInterface : Object { + public abstract void reboot (bool interactive) throws GLib.Error; + } + + private static SystemInterface? system_instance; + private static void get_system_instance () { + if (system_instance == null) { + try { + system_instance = Bus.get_proxy_sync ( + BusType.SYSTEM, + "org.freedesktop.login1", + "/org/freedesktop/login1" + ); + } catch (GLib.Error e) { + warning ("%s", e.message); + } + } + } +} diff --git a/src/Views/OperatingSystemView.vala b/src/Views/OperatingSystemView.vala index d8c15934d..8f86962ad 100644 --- a/src/Views/OperatingSystemView.vala +++ b/src/Views/OperatingSystemView.vala @@ -437,7 +437,7 @@ public class About.OperatingSystemView : Gtk.Grid { break; case State.RESTART: message_dialog.destroy (); - // Utils.restart (); + SystemUpgrade.restart (); break; } }); diff --git a/src/meson.build b/src/meson.build index 7d18d82f1..1dec14529 100644 --- a/src/meson.build +++ b/src/meson.build @@ -3,6 +3,7 @@ plug_files = files( 'Interfaces/FirmwareClient.vala', 'Interfaces/LoginManager.vala', 'Utils/ARMPartDecoder.vala', + 'Utils/SystemUpgrade.vala', 'Views/FirmwareReleaseView.vala', 'Views/FirmwareView.vala', 'Views/HardwareView.vala', From 156ad43a9c6d0d291f7511474a52e5b17cdc9fec Mon Sep 17 00:00:00 2001 From: Marius Meisenzahl Date: Sat, 29 Jan 2022 11:46:12 +0100 Subject: [PATCH 3/9] Check if system upgrade is available --- src/Utils/SystemUpgrade.vala | 32 ++++++++++++++++++++++++++++++ src/Views/OperatingSystemView.vala | 2 +- 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/src/Utils/SystemUpgrade.vala b/src/Utils/SystemUpgrade.vala index b13b38c88..c266eb23b 100644 --- a/src/Utils/SystemUpgrade.vala +++ b/src/Utils/SystemUpgrade.vala @@ -49,4 +49,36 @@ public class About.SystemUpgrade { } } } + + public static bool system_upgrade_available { + get { + get_system_upgrade_instance (); + + if (system_upgrade_instance == null) { + return false; + } + + return system_upgrade_instance.system_upgrade_available; + } + } + + [DBus (name = "io.elementary.SystemUpgrade")] + interface SystemUpgradeInterface : Object { + public abstract bool system_upgrade_available { get; } + } + + private static SystemUpgradeInterface? system_upgrade_instance; + private static void get_system_upgrade_instance () { + if (system_upgrade_instance == null) { + try { + system_upgrade_instance = Bus.get_proxy_sync ( + BusType.SESSION, + "io.elementary.settings-daemon", + "/io/elementary/settings_daemon" + ); + } catch (GLib.Error e) { + warning ("%s", e.message); + } + } + } } diff --git a/src/Views/OperatingSystemView.vala b/src/Views/OperatingSystemView.vala index 8f86962ad..14917a804 100644 --- a/src/Views/OperatingSystemView.vala +++ b/src/Views/OperatingSystemView.vala @@ -118,7 +118,7 @@ public class About.OperatingSystemView : Gtk.Grid { var upgrade_revealer = new Gtk.Revealer (); upgrade_revealer.add (upgrade_button); - upgrade_revealer.reveal_child = true; + upgrade_revealer.reveal_child = SystemUpgrade.system_upgrade_available; var bug_button = new Gtk.Button.with_label (_("Send Feedback")); From fc920c6de92eb963a9f08cc9eb2918382b7e7de9 Mon Sep 17 00:00:00 2001 From: Marius Meisenzahl Date: Sat, 29 Jan 2022 12:46:57 +0100 Subject: [PATCH 4/9] Interact with system upgrade daemon --- src/Utils/SystemUpgrade.vala | 61 ++++++++++++++++++++---------- src/Views/OperatingSystemView.vala | 24 ++++++------ 2 files changed, 52 insertions(+), 33 deletions(-) diff --git a/src/Utils/SystemUpgrade.vala b/src/Utils/SystemUpgrade.vala index c266eb23b..2e4cd4a97 100644 --- a/src/Utils/SystemUpgrade.vala +++ b/src/Utils/SystemUpgrade.vala @@ -19,10 +19,8 @@ * Authored by: Marius Meisenzahl */ -public class About.SystemUpgrade { - public static void restart () { - get_system_instance (); - +public class About.SystemUpgrade : Object { + public void restart () { try { system_instance.reboot (false); } catch (GLib.Error e) { @@ -30,13 +28,38 @@ public class About.SystemUpgrade { } } + public bool system_upgrade_available { + get { + if (system_upgrade_instance == null) { + return false; + } + + return system_upgrade_instance.system_upgrade_available; + } + } + + public void start_upgrade () { + if (system_upgrade_instance == null) { + system_upgrade_instance.start_upgrade (); + } + } + + public signal void system_upgrade_progress (int percentage); + + public signal void system_upgrade_finished (); + + construct { + get_system_instance (); + get_system_upgrade_instance (); + } + [DBus (name = "org.freedesktop.login1.Manager")] interface SystemInterface : Object { public abstract void reboot (bool interactive) throws GLib.Error; } - private static SystemInterface? system_instance; - private static void get_system_instance () { + private SystemInterface? system_instance; + private void get_system_instance () { if (system_instance == null) { try { system_instance = Bus.get_proxy_sync ( @@ -50,25 +73,19 @@ public class About.SystemUpgrade { } } - public static bool system_upgrade_available { - get { - get_system_upgrade_instance (); - - if (system_upgrade_instance == null) { - return false; - } - - return system_upgrade_instance.system_upgrade_available; - } - } - [DBus (name = "io.elementary.SystemUpgrade")] interface SystemUpgradeInterface : Object { public abstract bool system_upgrade_available { get; } + + public abstract void start_upgrade (); + + public signal void system_upgrade_progress (int percentage); + + public signal void system_upgrade_finished (); } - private static SystemUpgradeInterface? system_upgrade_instance; - private static void get_system_upgrade_instance () { + private SystemUpgradeInterface? system_upgrade_instance; + private void get_system_upgrade_instance () { if (system_upgrade_instance == null) { try { system_upgrade_instance = Bus.get_proxy_sync ( @@ -76,6 +93,10 @@ public class About.SystemUpgrade { "io.elementary.settings-daemon", "/io/elementary/settings_daemon" ); + + system_upgrade_instance.system_upgrade_progress.connect ((percentage) => { system_upgrade_progress (percentage); }); + + system_upgrade_instance.system_upgrade_finished.connect (() => { system_upgrade_finished (); }); } catch (GLib.Error e) { warning ("%s", e.message); } diff --git a/src/Views/OperatingSystemView.vala b/src/Views/OperatingSystemView.vala index 14917a804..2ee6191da 100644 --- a/src/Views/OperatingSystemView.vala +++ b/src/Views/OperatingSystemView.vala @@ -322,6 +322,8 @@ public class About.OperatingSystemView : Gtk.Grid { } private void show_upgrade_dialog () { + var system_upgrade = new SystemUpgrade (); + int seconds_remaining = RESTART_TIMEOUT; var message_dialog = new Granite.MessageDialog.with_image_from_icon_name ( @@ -392,22 +394,18 @@ public class About.OperatingSystemView : Gtk.Grid { suggested_button.visible = false; stack.set_visible_child (progress_view); - progress_view.notify["fraction"].connect (() => { - if (progress_view.fraction >= 1.0) { - suggested_button.activate (); - } - }); + progress_view.pulse (); - Timeout.add_seconds (1, () => { - progress_view.fraction += Random.next_double () * 0.1; + system_upgrade.system_upgrade_finished.connect (() => { + suggested_button.activate (); + }); - if (progress_view.fraction >= 1.0) { - return Source.REMOVE; - } - - return Source.CONTINUE; + system_upgrade.system_upgrade_progress.connect ((percentage) => { + progress_view.fraction = percentage / 100.0; }); + system_upgrade.start_upgrade (); + break; case State.SUCCESS: message_dialog.badge_icon = new ThemedIcon ("process-completed"); @@ -437,7 +435,7 @@ public class About.OperatingSystemView : Gtk.Grid { break; case State.RESTART: message_dialog.destroy (); - SystemUpgrade.restart (); + system_upgrade.restart (); break; } }); From a980d6bcdebb7089b0dff365daabb8895b0a0360 Mon Sep 17 00:00:00 2001 From: Marius Meisenzahl Date: Sat, 29 Jan 2022 13:11:26 +0100 Subject: [PATCH 5/9] Fix property access --- src/Views/OperatingSystemView.vala | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/Views/OperatingSystemView.vala b/src/Views/OperatingSystemView.vala index 2ee6191da..fc92bd1f4 100644 --- a/src/Views/OperatingSystemView.vala +++ b/src/Views/OperatingSystemView.vala @@ -19,11 +19,15 @@ */ public class About.OperatingSystemView : Gtk.Grid { + private SystemUpgrade system_upgrade; + private string support_url; private Gtk.Grid software_grid; construct { + system_upgrade = new SystemUpgrade (); + var style_provider = new Gtk.CssProvider (); style_provider.load_from_resource ("io/elementary/switchboard/system/OperatingSystemView.css"); @@ -118,7 +122,7 @@ public class About.OperatingSystemView : Gtk.Grid { var upgrade_revealer = new Gtk.Revealer (); upgrade_revealer.add (upgrade_button); - upgrade_revealer.reveal_child = SystemUpgrade.system_upgrade_available; + upgrade_revealer.reveal_child = system_upgrade.system_upgrade_available; var bug_button = new Gtk.Button.with_label (_("Send Feedback")); @@ -322,8 +326,6 @@ public class About.OperatingSystemView : Gtk.Grid { } private void show_upgrade_dialog () { - var system_upgrade = new SystemUpgrade (); - int seconds_remaining = RESTART_TIMEOUT; var message_dialog = new Granite.MessageDialog.with_image_from_icon_name ( From e70c9ff5a0e74d9999ef7b109ab340dd05511622 Mon Sep 17 00:00:00 2001 From: Marius Meisenzahl Date: Sat, 29 Jan 2022 16:42:39 +0100 Subject: [PATCH 6/9] Fix typo --- src/Utils/SystemUpgrade.vala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Utils/SystemUpgrade.vala b/src/Utils/SystemUpgrade.vala index 2e4cd4a97..e4731515f 100644 --- a/src/Utils/SystemUpgrade.vala +++ b/src/Utils/SystemUpgrade.vala @@ -39,7 +39,7 @@ public class About.SystemUpgrade : Object { } public void start_upgrade () { - if (system_upgrade_instance == null) { + if (system_upgrade_instance != null) { system_upgrade_instance.start_upgrade (); } } From 39033d9996f0d964f36a030941645042a616b976 Mon Sep 17 00:00:00 2001 From: Marius Meisenzahl Date: Sat, 29 Jan 2022 16:45:28 +0100 Subject: [PATCH 7/9] Refactor --- src/Views/OperatingSystemView.vala | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Views/OperatingSystemView.vala b/src/Views/OperatingSystemView.vala index fc92bd1f4..6c32d041b 100644 --- a/src/Views/OperatingSystemView.vala +++ b/src/Views/OperatingSystemView.vala @@ -363,6 +363,7 @@ public class About.OperatingSystemView : Gtk.Grid { stack.add (warning_view); var progress_view = new Gtk.ProgressBar (); + progress_view.pulse (); stack.add (progress_view); var success_view = new Gtk.Label ("") { @@ -396,8 +397,6 @@ public class About.OperatingSystemView : Gtk.Grid { suggested_button.visible = false; stack.set_visible_child (progress_view); - progress_view.pulse (); - system_upgrade.system_upgrade_finished.connect (() => { suggested_button.activate (); }); From 5e05e56c36c7a0bcbc9df6230005c35b83649c6b Mon Sep 17 00:00:00 2001 From: Marius Meisenzahl Date: Sun, 30 Jan 2022 16:39:58 +0100 Subject: [PATCH 8/9] Satisfy linter --- src/Views/OperatingSystemView.vala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Views/OperatingSystemView.vala b/src/Views/OperatingSystemView.vala index 6c32d041b..b372cfbc5 100644 --- a/src/Views/OperatingSystemView.vala +++ b/src/Views/OperatingSystemView.vala @@ -429,7 +429,7 @@ public class About.OperatingSystemView : Gtk.Grid { if (seconds_remaining == 0) { return Source.REMOVE; } - + return Source.CONTINUE; }); From b75cbc011485e62931cbce1e3947e5f20dd0bbfb Mon Sep 17 00:00:00 2001 From: Marius Meisenzahl Date: Sun, 25 Dec 2022 13:50:55 +0100 Subject: [PATCH 9/9] Rename OS version from Next to 7 --- src/Views/OperatingSystemView.vala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Views/OperatingSystemView.vala b/src/Views/OperatingSystemView.vala index b372cfbc5..5ad9ebec7 100644 --- a/src/Views/OperatingSystemView.vala +++ b/src/Views/OperatingSystemView.vala @@ -329,8 +329,8 @@ public class About.OperatingSystemView : Gtk.Grid { int seconds_remaining = RESTART_TIMEOUT; var message_dialog = new Granite.MessageDialog.with_image_from_icon_name ( - "elementary OS Next", - "To setup the installation of elementary OS Next, click Continue.", + "elementary OS 7", + "To setup the installation of elementary OS 7, click Continue.", "distributor-logo", Gtk.ButtonsType.CANCEL ) {