From ff0abadfa2cf0697e57a4c0fd4fc091deacaf5c5 Mon Sep 17 00:00:00 2001 From: Bkg2k Date: Mon, 15 Jul 2024 11:47:48 +0200 Subject: [PATCH] feat(frontend): add manual check in update menu --- projects/frontend/es-app/src/MainRunner.cpp | 4 +- projects/frontend/es-app/src/Upgrade.cpp | 51 ++++++++++---- projects/frontend/es-app/src/Upgrade.h | 70 +++++++++++-------- .../frontend/es-app/src/guis/MenuMessages.h | 3 +- .../es-app/src/guis/menus/MenuSystem.cpp | 2 +- .../es-app/src/guis/menus/MenuUpdates.cpp | 35 ++++++---- .../es-app/src/guis/menus/MenuUpdates.h | 1 + .../es-app/src/recalbox/RecalboxSystem.cpp | 2 +- 8 files changed, 105 insertions(+), 63 deletions(-) diff --git a/projects/frontend/es-app/src/MainRunner.cpp b/projects/frontend/es-app/src/MainRunner.cpp index 7c0b88d3da..64b0e27f60 100644 --- a/projects/frontend/es-app/src/MainRunner.cpp +++ b/projects/frontend/es-app/src/MainRunner.cpp @@ -513,7 +513,7 @@ void MainRunner::CheckUpdateFailed(WindowManager& window) Path flag(sUpgradeFailedFlag); if (flag.Exists()) { - String version = Upgrade::CurrentVersion(); + String version = Upgrade::Instance().CurrentVersion(); String message = _("The upgrade process has failed. You are back on Recalbox %s.\nPlease retry to upgrade your Recalbox, and contact the team on https://forum.recalbox.com if the problem persists.") .Replace("%s", version.c_str()); window.pushGui(new GuiMsgBoxScroll(window, _("THE UPGRADE HAS FAILED"), message, _("OK"), []{}, "", nullptr, "", nullptr, TextAlignment::Left)); @@ -527,7 +527,7 @@ void MainRunner::CheckUpdateCorrupted(WindowManager& window) Path flag(sUpgradeCorruptedFlag); if (flag.Exists()) { - String version = Upgrade::CurrentVersion(); + String version = Upgrade::Instance().CurrentVersion(); String message = _("One or more files are corrupted. You are back on Recalbox %s.\nPlease retry to upgrade your Recalbox, check your Recalbox storage (SD Card, USB Key or hard drive).\nContact the team on https://forum.recalbox.com if the problem persists.") .Replace("%s", version.c_str()); window.pushGui(new GuiMsgBoxScroll(window, _("THE UPGRADE IS CORRUPTED"), message, _("OK"), []{}, "", nullptr, "", nullptr, TextAlignment::Left)); diff --git a/projects/frontend/es-app/src/Upgrade.cpp b/projects/frontend/es-app/src/Upgrade.cpp index 4439e8a22e..e95894147b 100755 --- a/projects/frontend/es-app/src/Upgrade.cpp +++ b/projects/frontend/es-app/src/Upgrade.cpp @@ -17,18 +17,14 @@ #include #include -String Upgrade::mDomainName; -String Upgrade::mRemoteVersion; -String Upgrade::mLocalVersion; -String Upgrade::mRemoteReleaseNote; -String Upgrade::mLocalReleaseNote; - Upgrade::UpdatePopup* Upgrade::UpdatePopup::mInstance = nullptr; Upgrade::Upgrade(WindowManager& window, bool firstRun) - : mWindow(window) + : StaticLifeCycleControler("upgrade") + , mWindow(window) , mSender(*this) , mFirstRun(firstRun) + , mManualCheckPending(false) { Thread::Start("Upgrade"); } @@ -50,7 +46,9 @@ void Upgrade::Run() int waitForSeconds = mFirstRun ? 15 : 3600; while (IsRunning()) { - if (mSignal.WaitSignal(waitForSeconds * 1000LL)) return; + if (mSignal.WaitSignal(waitForSeconds * 1000LL)) + if (!mManualCheckPending) + return; // Next checks, once an hour waitForSeconds = 3600; @@ -82,7 +80,7 @@ void Upgrade::Run() mPopupMessage += _("You're strongly recommended to update your Recalbox.\nNo support will be provided for older versions!"); // Message box only if the option is on - if (RecalboxConf::Instance().AsBool("updates.enabled")) + if (RecalboxConf::Instance().GetUpdatesEnabled() || mManualCheckPending) { while (mWindow.HasGui() || mWindow.isSleeping()) Thread::Sleep(5000); @@ -100,9 +98,21 @@ void Upgrade::Run() } } - mSender.Send(); + mSender.Send(true); + // Reset manual check + mManualCheckPending = false; + } + else + { + { LOG(LogInfo) << "[Update] Remote version match local version. No update."; } + if (mManualCheckPending) + { + mMessageBoxMessage = (_F(_("Remote version {0} match the currently running version. No update required.")) / mRemoteVersion).ToString(); + mSender.Send(false); + } + // Reset manual check + mManualCheckPending = false; } - else { LOG(LogInfo) << "[Update] Remote version match local version. No update."; } } else { LOG(LogError) << "[Update] Invalid remote version! " << mRemoteVersion; } } @@ -114,14 +124,19 @@ void Upgrade::Run() } } -void Upgrade::ReceiveSyncMessage() +void Upgrade::ReceiveSyncMessage(bool updateAvaiable) { // Volatile popup - mWindow.InfoPopupAdd(new GuiInfoPopup(mWindow, mPopupMessage, 10, PopupType::Recalbox)); + if (updateAvaiable) + mWindow.InfoPopupAdd(new GuiInfoPopup(mWindow, mPopupMessage, 10, PopupType::Recalbox)); // Messagebox - if (!mMessageBoxMessage.empty()) - UpdatePopup::Show(&mWindow, mMessageBoxMessage); + if (updateAvaiable) + { + if (!mMessageBoxMessage.empty()) + UpdatePopup::Show(&mWindow, this, mMessageBoxMessage); + } + else mWindow.displayMessage(mMessageBoxMessage); } String Upgrade::GetDomainName() @@ -287,3 +302,9 @@ String Upgrade::GetRemoteReleaseVersion() // Return version return releaseNote; } + +void Upgrade::DoManualCheck() +{ + mManualCheckPending = true; + mSignal.Fire(); +} diff --git a/projects/frontend/es-app/src/Upgrade.h b/projects/frontend/es-app/src/Upgrade.h index 0423f1eb3b..d0954431bb 100644 --- a/projects/frontend/es-app/src/Upgrade.h +++ b/projects/frontend/es-app/src/Upgrade.h @@ -12,8 +12,9 @@ // Forward declaration class WindowManager; -class Upgrade: private Thread - , private ISyncMessageReceiver +class Upgrade: public StaticLifeCycleControler + , private Thread + , private ISyncMessageReceiver { public: //! Local version file @@ -30,7 +31,7 @@ class Upgrade: private Thread * @param window main Window * @param firstRun True if the front end just lauched, false otherwise */ - explicit Upgrade(WindowManager& window, bool firstRun); + Upgrade(WindowManager& window, bool firstRun); /*! * @brief Destructor @@ -41,48 +42,48 @@ class Upgrade: private Thread * @brief Return remote version. * @return Remote version */ - static String NewVersion() { return mRemoteVersion.empty() ? mLocalVersion : mRemoteVersion; } + String NewVersion() { return mRemoteVersion.empty() ? mLocalVersion : mRemoteVersion; } /*! * @brief Return trimmed current version. * @return Current version */ - static String CurrentVersion() { return Files::LoadFile(Path(sLocalVersionFile)).Trim(" \t\r\n"); } + String CurrentVersion() { return Files::LoadFile(Path(sLocalVersionFile)).Trim(" \t\r\n"); } /*! * @brief Return trimmed current version. * @return Current version */ - static String CurrentArch() { return Files::LoadFile(Path(sLocalArchFile)).Trim(" \t\r\n").Replace('_', '/'); } + String CurrentArch() { return Files::LoadFile(Path(sLocalArchFile)).Trim(" \t\r\n").Replace('_', '/'); } /*! * @brief Return remote releasenote * @return Remote release note */ - static String NewReleaseNote() { return mRemoteReleaseNote.empty() ? mLocalReleaseNote : mRemoteReleaseNote; } + String NewReleaseNote() { return mRemoteReleaseNote.empty() ? mLocalReleaseNote : mRemoteReleaseNote; } /*! * @brief Return Tar url * @return tar url */ - static String TarUrl(); + String TarUrl(); /*! * @brief Return remote version. * @return Remote version */ - static String ImageUrl(); + String ImageUrl(); /*! * @brief Return remote version. * @return Remote version */ - static String HashUrl(); + String HashUrl(); /*! * @brief Check if there is a pending update */ - static bool PendingUpdate() + bool PendingUpdate() { if (mRemoteVersion.empty()) return false; return mRemoteVersion != mLocalVersion; @@ -92,18 +93,23 @@ class Upgrade: private Thread * @brief Check if the network is ready * @return True if the network is ready */ - static bool NetworkReady() { return !GetDomainName().empty(); } + bool NetworkReady() { return !GetDomainName().empty(); } + + /*! + * @brief Check if an update is available, immediately + */ + void DoManualCheck(); private: class UpdatePopup : public GuiMsgBoxScroll { public: //! Build & show the popup if it does not already exists - static void Show(WindowManager* window, const String& message) + static void Show(WindowManager* window, Upgrade* upgrade, const String& message) { if (mInstance == nullptr) { - mInstance = new UpdatePopup(window, message); + mInstance = new UpdatePopup(window, upgrade, message); window->pushGui(mInstance); } } @@ -116,15 +122,15 @@ class Upgrade: private Thread static UpdatePopup* mInstance; //! Launch update window - static void LaunchUpdate(WindowManager* window) + static void LaunchUpdate(WindowManager* window, Upgrade* upgrade) { - window->pushGui(new GuiUpdateRecalbox(*window, TarUrl(), ImageUrl(), HashUrl(), NewVersion())); + window->pushGui(new GuiUpdateRecalbox(*window, upgrade->TarUrl(), upgrade->ImageUrl(), upgrade->HashUrl(), upgrade->NewVersion())); } //! Default constructor - UpdatePopup(WindowManager* window, const String& message) + UpdatePopup(WindowManager* window, Upgrade* upgrade, const String& message) : GuiMsgBoxScroll(*window, _("AN UPDATE IS AVAILABLE FOR YOUR RECALBOX"), message, _("LATER"), nullptr, _("UPDATE NOW"), - std::bind(UpdatePopup::LaunchUpdate, window), String::Empty, nullptr, TextAlignment::Left) {} + std::bind(UpdatePopup::LaunchUpdate, window, upgrade), String::Empty, nullptr, TextAlignment::Left) {} }; //! Release DNS @@ -141,7 +147,7 @@ class Upgrade: private Thread //! MainWindow WindowManager& mWindow; //! Syncronous event to display popup - SyncMessageSender mSender; + SyncMessageSender mSender; //! Signal used to stop the thread Signal mSignal; //! Built popup message @@ -149,18 +155,21 @@ class Upgrade: private Thread //! Build MessageBox message String mMessageBoxMessage; //! Download URL - static String mDomainName; + String mDomainName; //! Remote version - static String mRemoteVersion; + String mRemoteVersion; //! Local version - static String mLocalVersion; + String mLocalVersion; //! Remote version - static String mRemoteReleaseNote; + String mRemoteReleaseNote; //! Local version - static String mLocalReleaseNote; + String mLocalReleaseNote; //! First run? bool mFirstRun; + //! Manual check required + bool mManualCheckPending; + /* * Thread implementation */ @@ -174,26 +183,25 @@ class Upgrade: private Thread * Synchronous event implementation */ - /*! * @brief Receive synchronous message */ - void ReceiveSyncMessage() override; + void ReceiveSyncMessage(bool value) override; /*! * @brief Get update url from DNS TXT records */ - static String GetDomainName(); + String GetDomainName(); /*! * @brief Get remote version */ - static String GetRemoteVersion(); + String GetRemoteVersion(); /*! * @brief Get remote version */ - static String GetRemoteReleaseVersion(); + String GetRemoteReleaseVersion(); /*! * @brief Replace machine parameters parameters in the given url (Arch, uuid, domain, ...) @@ -201,14 +209,14 @@ class Upgrade: private Thread * @param ext Optional extention * @return Final url */ - static String ReplaceMachineParameters(const String& url, const String& ext); + String ReplaceMachineParameters(const String& url, const String& ext); /*! * @brief Validate the given version * @param version Version to validate * @return True if the given version has been identified as valid, false otherwise */ - static bool ValidateVersion(const String& version); + bool ValidateVersion(const String& version); }; diff --git a/projects/frontend/es-app/src/guis/MenuMessages.h b/projects/frontend/es-app/src/guis/MenuMessages.h index c8b6197fbf..d287251420 100755 --- a/projects/frontend/es-app/src/guis/MenuMessages.h +++ b/projects/frontend/es-app/src/guis/MenuMessages.h @@ -20,7 +20,8 @@ class MenuMessages #define MENUMESSAGE_QUIT_HELP_MSG "Shows the quit menu to reboot or shutdown Recalbox." #define MENUMESSAGE_UPDATE_HELP_MSG "Manage your recalbox updates. Select the update type. Activate update check." - #define MENUMESSAGE_START_UPDATE_HELP_MSG "Check if an update is available, and start the update process." + #define MENUMESSAGE_START_UPDATE_HELP_MSG "UAn update is availabel ! Start the update process." + #define MENUMESSAGE_CHECK_UPDATE_HELP_MSG "Check if an update is available, right now." #define MENUMESSAGE_UPDATE_TYPE_HELP_MSG "Stable updates will check for updates on stable recalbox releases. Stable updates are tested and approved by the recalbox team and their testers.\nUnstable updates allows you to get the latest recalbox features by checking our unstable repository. You can test and validate with us the very last version of recalbox.\nIf you choose unstable update, be so kind to report issues on the recalbox-os issue board (https://github.com/recalbox/recalbox-os/issues)" #define MENUMESSAGE_UPDATE_CHECK_HELP_MSG "Automatically check if an update is avaialble. If so, it notifies you with a message." #define MENUMESSAGE_UPDATE_VERSION_HELP_MSG "Shows the current available update version." diff --git a/projects/frontend/es-app/src/guis/menus/MenuSystem.cpp b/projects/frontend/es-app/src/guis/menus/MenuSystem.cpp index 1c74db72df..83105cc429 100644 --- a/projects/frontend/es-app/src/guis/menus/MenuSystem.cpp +++ b/projects/frontend/es-app/src/guis/menus/MenuSystem.cpp @@ -20,7 +20,7 @@ MenuSystem::MenuSystem(WindowManager& window, SystemManager& systemManager) void MenuSystem::BuildMenuItems() { // Version - String version = Upgrade::CurrentVersion(); + String version = Upgrade::Instance().CurrentVersion(); String arch = "unknown"; switch(Board::Instance().GetBoardType()) { diff --git a/projects/frontend/es-app/src/guis/menus/MenuUpdates.cpp b/projects/frontend/es-app/src/guis/menus/MenuUpdates.cpp index f846bb1225..82cbf2ac5c 100644 --- a/projects/frontend/es-app/src/guis/menus/MenuUpdates.cpp +++ b/projects/frontend/es-app/src/guis/menus/MenuUpdates.cpp @@ -23,15 +23,22 @@ void MenuUpdates::BuildMenuItems() AddSwitch(_("CHECK UPDATES"), RecalboxConf::Instance().GetUpdatesEnabled(), (int)Components::Enable, this, _(MENUMESSAGE_UPDATE_CHECK_HELP_MSG)); // Display available update version - bool update = Upgrade::PendingUpdate(); + bool update = Upgrade::Instance().PendingUpdate(); AddText(_("AVAILABLE UPDATE"), update ? _("YES") : _("NO"), _(MENUMESSAGE_UPDATE_VERSION_HELP_MSG)); // Display available update changelog - AddSubMenu(_("UPDATE CHANGELOG"), (int)Components::Changelog, this, _(MENUMESSAGE_UPDATE_CHANGELOG_HELP_MSG), !update); - - // Start update - AddSubMenu(_("START UPDATE"), (int)Components::StartUpdate, this, _(MENUMESSAGE_START_UPDATE_HELP_MSG), !update); + if (update) + { + AddSubMenu(_("UPDATE CHANGELOG"), (int) Components::Changelog, this, _(MENUMESSAGE_UPDATE_CHANGELOG_HELP_MSG)); + // Start update + AddSubMenu(_("START UPDATE"), (int) Components::StartUpdate, this, _(MENUMESSAGE_START_UPDATE_HELP_MSG)); + } + else if (RecalboxSystem::hasIpAdress(false)) + { + // Start update + AddSubMenu(_("CHECK FOR UPDATE NOW"), (int)Components::CheckUpdate, this, _(MENUMESSAGE_CHECK_UPDATE_HELP_MSG)); + } // Enable updates if ( #ifdef BETA @@ -61,23 +68,27 @@ void MenuUpdates::MenuSwitchChanged(int id, bool& status) void MenuUpdates::SubMenuSelected(int id) { - if ((Components)id == Components::Changelog) + Upgrade& upgrade = Upgrade::Instance(); + if ((Components) id == Components::Changelog) { - String changelog = Upgrade::NewReleaseNote(); + String changelog = upgrade.NewReleaseNote(); if (!changelog.empty()) { const String& message = changelog; - String updateVersion = Upgrade::NewVersion(); + String updateVersion = upgrade.NewVersion(); mWindow.displayScrollMessage(_("AN UPDATE IS AVAILABLE FOR YOUR RECALBOX"), - _("NEW VERSION:") + ' ' + updateVersion + "\n" + - _("UPDATE CHANGELOG:") + "\n" + message); + _("NEW VERSION:") + ' ' + updateVersion + "\n" + _("UPDATE CHANGELOG:") + "\n" + + message); } else mWindow.displayMessage(_("AN UPDATE IS AVAILABLE FOR YOUR RECALBOX")); } - else if ((Components)id == Components::StartUpdate) + else if ((Components) id == Components::StartUpdate) + mWindow.pushGui(new GuiUpdateRecalbox(mWindow, upgrade.TarUrl(), upgrade.ImageUrl(), upgrade.HashUrl(), upgrade.NewVersion())); + else if ((Components) id == Components::CheckUpdate) { - mWindow.pushGui(new GuiUpdateRecalbox(mWindow, Upgrade::TarUrl(), Upgrade::ImageUrl(), Upgrade::HashUrl(), Upgrade::NewVersion())); + upgrade.DoManualCheck(); + mWindow.CloseAll(); } } diff --git a/projects/frontend/es-app/src/guis/menus/MenuUpdates.h b/projects/frontend/es-app/src/guis/menus/MenuUpdates.h index 49a55c70a1..f2aee7716c 100644 --- a/projects/frontend/es-app/src/guis/menus/MenuUpdates.h +++ b/projects/frontend/es-app/src/guis/menus/MenuUpdates.h @@ -34,6 +34,7 @@ class MenuUpdates : public Menu Changelog, StartUpdate, UpdateType, + CheckUpdate, }; //! Get Update type List diff --git a/projects/frontend/es-app/src/recalbox/RecalboxSystem.cpp b/projects/frontend/es-app/src/recalbox/RecalboxSystem.cpp index 58bc012078..753f6c881c 100755 --- a/projects/frontend/es-app/src/recalbox/RecalboxSystem.cpp +++ b/projects/frontend/es-app/src/recalbox/RecalboxSystem.cpp @@ -480,7 +480,7 @@ std::pair RecalboxSystem::execute(const String& command) bool RecalboxSystem::ping() { - return Upgrade::NetworkReady(); + return Upgrade::Instance().NetworkReady(); } std::pair RecalboxSystem::getSDLBatteryInfo() -- GitLab