From ef63ee267c78136773ed23156ad85a75e650a7b6 Mon Sep 17 00:00:00 2001 From: Wojtek Rzepecki Date: Fri, 19 Feb 2021 09:09:10 +0100 Subject: [PATCH] [EGD-5304] Add new way of system close Unified method of closing the system orchestrated by system manager --- module-apps/Application.cpp | 5 +- module-apps/Application.hpp | 15 +-- module-apps/ApplicationLauncher.hpp | 4 +- .../ApplicationDesktop.cpp | 18 ++- .../ApplicationDesktop.hpp | 3 +- .../application-desktop/CMakeLists.txt | 2 + .../presenter/PowerOffPresenter.cpp | 19 +++ .../presenter/PowerOffPresenter.hpp | 20 +++ .../windows/DeadBatteryWindow.cpp | 11 +- .../windows/DeadBatteryWindow.hpp | 4 - .../windows/LogoWindow.cpp | 36 +++++ .../windows/LogoWindow.hpp | 19 +++ .../application-desktop/windows/Names.hpp | 1 + .../windows/PowerOffWindow.cpp | 27 +--- .../windows/PowerOffWindow.hpp | 4 +- .../application-desktop/windows/Reboot.cpp | 10 +- .../application-desktop/windows/Reboot.hpp | 4 +- .../service-antenna/ServiceAntenna.cpp | 5 + .../service-antenna/ServiceAntenna.hpp | 2 + .../model/ApplicationManager.cpp | 42 +++--- .../service-appmgr/service-appmgr/Actions.hpp | 2 +- .../messages/UserPowerDownRequest.hpp | 13 ++ .../model/ApplicationManager.hpp | 4 +- .../service-audio/ServiceAudio.cpp | 5 + .../service-audio/ServiceAudio.hpp | 2 + .../service-bluetooth/ServiceBluetooth.cpp | 5 + .../service-bluetooth/ServiceBluetooth.hpp | 1 + .../service-cellular/ServiceCellular.cpp | 6 +- .../service-cellular/ServiceCellular.hpp | 1 + module-services/service-db/ServiceDB.cpp | 5 + module-services/service-db/ServiceDB.hpp | 2 + .../test-service-db-settings-api.cpp | 24 ++-- .../test-service-db-settings-testapps.hpp | 20 ++- .../service-desktop/ServiceDesktop.cpp | 5 + .../endpoints/backup/BackupRestore.cpp | 2 +- .../endpoints/factoryReset/FactoryReset.cpp | 2 +- .../service-desktop/ServiceDesktop.hpp | 1 + module-services/service-eink/ServiceEink.cpp | 5 + module-services/service-eink/ServiceEink.hpp | 1 + .../service-evtmgr/EventManager.cpp | 5 + .../service-evtmgr/EventManager.hpp | 2 + module-services/service-fota/ServiceFota.cpp | 5 + .../service-fota/service-fota/ServiceFota.hpp | 2 + module-services/service-gui/ServiceGUI.cpp | 27 ++-- module-services/service-gui/ServiceGUI.hpp | 3 + module-services/service-lwip/ServiceLwIP.cpp | 5 + .../service-lwip/service-lwip/ServiceLwIP.hpp | 1 + module-services/service-time/ServiceTime.cpp | 5 + module-services/service-time/ServiceTime.hpp | 1 + module-sys/Service/Common.hpp | 8 ++ module-sys/Service/Message.cpp | 14 ++ module-sys/Service/Message.hpp | 16 +++ module-sys/Service/Service.cpp | 15 +++ module-sys/Service/Service.hpp | 5 + module-sys/Service/Timer.cpp | 6 + module-sys/Service/Timer.hpp | 1 + module-sys/SystemManager/SystemManager.cpp | 127 ++++++++++++++---- module-sys/SystemManager/SystemManager.hpp | 32 ++++- .../SystemManager/doc/SystemCloseSequence.md | 10 ++ .../doc/system_close_procedure_brownout.puml | 27 ++++ .../doc/system_close_procedure_brownout.svg | 37 +++++ .../doc/system_close_procedure_user.puml | 32 +++++ .../doc/system_close_procedure_user.svg | 42 ++++++ .../messages/SystemManagerMessage.hpp | 10 -- source/main.cpp | 2 +- 65 files changed, 639 insertions(+), 158 deletions(-) create mode 100644 module-apps/application-desktop/presenter/PowerOffPresenter.cpp create mode 100644 module-apps/application-desktop/presenter/PowerOffPresenter.hpp create mode 100644 module-apps/application-desktop/windows/LogoWindow.cpp create mode 100644 module-apps/application-desktop/windows/LogoWindow.hpp create mode 100644 module-services/service-appmgr/service-appmgr/messages/UserPowerDownRequest.hpp create mode 100644 module-sys/SystemManager/doc/SystemCloseSequence.md create mode 100644 module-sys/SystemManager/doc/system_close_procedure_brownout.puml create mode 100644 module-sys/SystemManager/doc/system_close_procedure_brownout.svg create mode 100644 module-sys/SystemManager/doc/system_close_procedure_user.puml create mode 100644 module-sys/SystemManager/doc/system_close_procedure_user.svg diff --git a/module-apps/Application.cpp b/module-apps/Application.cpp index 9c41d6aef98d96c0c6d310f846195cbf2ae073be..d8edd123bdb591c3fb015b5a4c1e6ed58553f86b 100644 --- a/module-apps/Application.cpp +++ b/module-apps/Application.cpp @@ -22,6 +22,7 @@ #include #include #include +#include #include "service-gui/messages/DrawMessage.hpp" // for DrawMessage #include "task.h" // for xTaskGetTic... #include "windows/AppWindow.hpp" // for AppWindow @@ -158,12 +159,14 @@ namespace app window->updateTime(); auto message = std::make_shared(window->buildDrawList(), mode); - if (shutdownInProgress) { + + if (systemCloseInProgress) { message->setCommandType(service::gui::DrawMessage::Type::SHUTDOWN); } else if (suspendInProgress) { message->setCommandType(service::gui::DrawMessage::Type::SUSPEND); } + bus.sendUnicast(std::move(message), service::name::gui); } diff --git a/module-apps/Application.hpp b/module-apps/Application.hpp index 5b9211bbb569b7b947a36d4098efa90c8b542748..530c3fb336cdbcaf532c63c4e2d139933bda8083 100644 --- a/module-apps/Application.hpp +++ b/module-apps/Application.hpp @@ -267,11 +267,12 @@ namespace app { suspendInProgress = val; }; - /// see shutdownInProgress documentation - virtual void setShutdownFlag() + + // Latching close system in progress flag + virtual void setSystemCloseInProgress() { - shutdownInProgress = true; - }; + systemCloseInProgress = true; + } bool setVolume(const audio::Volume &value, const audio::Profile::Type &profileType, @@ -368,10 +369,8 @@ namespace app /// sent to gui service. If suspend is true, application manager will receive information from both eink and gui /// services if last rendering mesage will be processed. bool suspendInProgress = false; - /// Flag defines case when display needs to be refreshed before closing the system. If flag is set to true next - /// set of rendering commands will carry information to GUI service that system needs to be closed. After - /// displaying the screen GUI will notify application manager to request system shutdown. - bool shutdownInProgress = false; + + bool systemCloseInProgress = false; /// Storage for asynchronous tasks callbacks. std::unique_ptr callbackStorage; friend class AsyncTask; // Async tasks need access to application internals, e.g. callback storage, to make diff --git a/module-apps/ApplicationLauncher.hpp b/module-apps/ApplicationLauncher.hpp index 26d68a302e2ffc8bc5d5085fcddbdb4bedfff558..9726675b1e26ef9cf97759e7e66e64c51973a4e7 100644 --- a/module-apps/ApplicationLauncher.hpp +++ b/module-apps/ApplicationLauncher.hpp @@ -93,14 +93,14 @@ namespace app { parent = (caller == nullptr ? "" : caller->GetName()); handle = std::make_shared(name, parent); - return sys::SystemManager::RunService(handle, caller); + return sys::SystemManager::RunApplication(handle, caller); } bool runBackground(sys::Service *caller) override { parent = (caller == nullptr ? "" : caller->GetName()); handle = std::make_shared(name, parent, true); - return sys::SystemManager::RunService(handle, caller); + return sys::SystemManager::RunApplication(handle, caller); } }; diff --git a/module-apps/application-desktop/ApplicationDesktop.cpp b/module-apps/application-desktop/ApplicationDesktop.cpp index 9ea8eab23889e22fde3a79994d737cedd4e381e6..ee03dbf981fc392e974e1d02eaa642057b8c9de5 100644 --- a/module-apps/application-desktop/ApplicationDesktop.cpp +++ b/module-apps/application-desktop/ApplicationDesktop.cpp @@ -9,6 +9,7 @@ #include "windows/PinLockWindow.hpp" #include "windows/PowerOffWindow.hpp" #include "windows/DeadBatteryWindow.hpp" +#include "windows/LogoWindow.hpp" #include "windows/LockedInfoWindow.hpp" #include "windows/Reboot.hpp" #include "windows/Update.hpp" @@ -17,6 +18,7 @@ #include "windows/MmiPullWindow.hpp" #include "windows/MmiPushWindow.hpp" #include "windows/MmiInternalMsgWindow.hpp" +#include "presenter/PowerOffPresenter.hpp" #include "AppWindow.hpp" #include "data/LockPhoneData.hpp" @@ -105,10 +107,17 @@ namespace app }); addActionReceiver(app::manager::actions::SystemBrownout, [this](auto &&data) { + setSystemCloseInProgress(); switchWindow(app::window::name::dead_battery, std::move(data)); return actionHandled(); }); + addActionReceiver(app::manager::actions::DisplayLogoAtExit, [this](auto &&data) { + setSystemCloseInProgress(); + switchWindow(app::window::name::logo_window, std::move(data)); + return actionHandled(); + }); + addActionReceiver(app::manager::actions::AutoLock, [this](auto &&data) { if (lockHandler.isScreenLocked()) { return actionHandled(); @@ -401,16 +410,21 @@ namespace app return std::make_unique(app); }); windowsFactory.attach(desktop_poweroff, [](Application *app, const std::string newname) { - return std::make_unique(app); + auto presenter = std::make_unique(app); + return std::make_unique(app, std::move(presenter)); }); windowsFactory.attach(dead_battery, [](Application *app, const std::string newname) { return std::make_unique(app); }); + windowsFactory.attach(logo_window, [](Application *app, const std::string newname) { + return std::make_unique(app); + }); windowsFactory.attach(desktop_locked, [](Application *app, const std::string newname) { return std::make_unique(app); }); windowsFactory.attach(desktop_reboot, [](Application *app, const std::string newname) { - return std::make_unique(app); + auto presenter = std::make_unique(app); + return std::make_unique(app, std::move(presenter)); }); windowsFactory.attach(desktop_update, [](Application *app, const std::string newname) { return std::make_unique(app); diff --git a/module-apps/application-desktop/ApplicationDesktop.hpp b/module-apps/application-desktop/ApplicationDesktop.hpp index 94bbc1f0edc46228cf35d3019a2e5e14d4a616bd..201095aff0df7b9c6dbb71fa5cbd4b3ca5d096dd 100644 --- a/module-apps/application-desktop/ApplicationDesktop.hpp +++ b/module-apps/application-desktop/ApplicationDesktop.hpp @@ -123,7 +123,8 @@ namespace app manager::actions::ShowMMIResult, manager::actions::DisplayCMEError, manager::actions::DisplayLowBatteryNotification, - manager::actions::SystemBrownout}}; + manager::actions::SystemBrownout, + manager::actions::DisplayLogoAtExit}}; } }; diff --git a/module-apps/application-desktop/CMakeLists.txt b/module-apps/application-desktop/CMakeLists.txt index 286598a655efc5995d3266fb9fd298ac4264a211..881c992756c6ee21f1086c688b143a7563ee01e6 100644 --- a/module-apps/application-desktop/CMakeLists.txt +++ b/module-apps/application-desktop/CMakeLists.txt @@ -28,6 +28,7 @@ target_sources( ${PROJECT_NAME} "${CMAKE_CURRENT_LIST_DIR}/windows/MenuWindow.cpp" "${CMAKE_CURRENT_LIST_DIR}/windows/PowerOffWindow.cpp" "${CMAKE_CURRENT_LIST_DIR}/windows/DeadBatteryWindow.cpp" + "${CMAKE_CURRENT_LIST_DIR}/windows/LogoWindow.cpp" "${CMAKE_CURRENT_LIST_DIR}/windows/LockedInfoWindow.cpp" "${CMAKE_CURRENT_LIST_DIR}/windows/Reboot.cpp" "${CMAKE_CURRENT_LIST_DIR}/windows/Update.cpp" @@ -38,6 +39,7 @@ target_sources( ${PROJECT_NAME} "${CMAKE_CURRENT_LIST_DIR}/windows/MmiInternalMsgWindow.cpp" "${CMAKE_CURRENT_LIST_DIR}/windows/ScreenLockBaseBox.cpp" "${CMAKE_CURRENT_LIST_DIR}/windows/LockWindow.cpp" + "${CMAKE_CURRENT_LIST_DIR}/presenter/PowerOffPresenter.cpp" PUBLIC "${CMAKE_CURRENT_LIST_DIR}/ApplicationDesktop.hpp" "${CMAKE_CURRENT_LIST_DIR}/data/LockPhoneData.hpp" diff --git a/module-apps/application-desktop/presenter/PowerOffPresenter.cpp b/module-apps/application-desktop/presenter/PowerOffPresenter.cpp new file mode 100644 index 0000000000000000000000000000000000000000..ee4e9e972138d9e32631b15822f6c151fb3d7d48 --- /dev/null +++ b/module-apps/application-desktop/presenter/PowerOffPresenter.cpp @@ -0,0 +1,19 @@ +// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved. +// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md + +#include "PowerOffPresenter.hpp" +#include +#include + +namespace gui +{ + PowerOffPresenter::PowerOffPresenter(app::Application *app) : application(app) + {} + + void PowerOffPresenter::powerOff() + { + auto msg = std::make_shared(); + application->bus.sendUnicast(std::move(msg), service::name::system_manager); + } + +} // namespace gui diff --git a/module-apps/application-desktop/presenter/PowerOffPresenter.hpp b/module-apps/application-desktop/presenter/PowerOffPresenter.hpp new file mode 100644 index 0000000000000000000000000000000000000000..8dba0cc7d33d8a1f4476ecec29a2964f1924455b --- /dev/null +++ b/module-apps/application-desktop/presenter/PowerOffPresenter.hpp @@ -0,0 +1,20 @@ +// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved. +// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md + +#pragma once + +#include + +namespace gui +{ + class PowerOffPresenter + { + public: + PowerOffPresenter(app::Application *app); + void powerOff(); + + private: + app::Application *application; + }; + +} // namespace gui diff --git a/module-apps/application-desktop/windows/DeadBatteryWindow.cpp b/module-apps/application-desktop/windows/DeadBatteryWindow.cpp index 5ca822af2b2d982a315ee43daa65e572298fa2a2..cca27e0ccd4518c584965f81860e5da4181d7bb2 100644 --- a/module-apps/application-desktop/windows/DeadBatteryWindow.cpp +++ b/module-apps/application-desktop/windows/DeadBatteryWindow.cpp @@ -8,8 +8,6 @@ #include "gui/widgets/TopBar.hpp" #include "log/log.hpp" #include -#include -#include namespace gui { @@ -36,18 +34,11 @@ namespace gui AppWindow::buildInterface(); bottomBar->setVisible(false); topBar->setVisible(false); - - image = new gui::Image(this, IMG_POS_X, IMG_POS_Y, 0, 0, "dead_battery_W_G"); - } - - void DeadBatteryWindow::onBeforeShow(ShowMode mode, SwitchData *data) - { - app::manager::Controller::sendAction(application, app::manager::actions::CloseSystem); + new gui::Image(this, IMG_POS_X, IMG_POS_Y, 0, 0, "dead_battery_W_G"); } void DeadBatteryWindow::destroyInterface() { erase(); - image = nullptr; } } /* namespace gui */ diff --git a/module-apps/application-desktop/windows/DeadBatteryWindow.hpp b/module-apps/application-desktop/windows/DeadBatteryWindow.hpp index 4c30724e9c6be7fdb46c4677ff62f93323eafb5e..9495adf10724bbcbfe5243dffb922f89ad1887fa 100644 --- a/module-apps/application-desktop/windows/DeadBatteryWindow.hpp +++ b/module-apps/application-desktop/windows/DeadBatteryWindow.hpp @@ -15,10 +15,6 @@ namespace gui void rebuild() override; void buildInterface() override; void destroyInterface() override; - void onBeforeShow(ShowMode mode, SwitchData *data) override; - - private: - gui::Image *image = nullptr; }; } /* namespace gui */ diff --git a/module-apps/application-desktop/windows/LogoWindow.cpp b/module-apps/application-desktop/windows/LogoWindow.cpp new file mode 100644 index 0000000000000000000000000000000000000000..5f182c4c3d359a24459c89a54d032d9b42d299d5 --- /dev/null +++ b/module-apps/application-desktop/windows/LogoWindow.cpp @@ -0,0 +1,36 @@ +// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved. +// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md + +#include "LogoWindow.hpp" +#include "gui/widgets/Image.hpp" +#include "gui/widgets/BottomBar.hpp" +#include "gui/widgets/TopBar.hpp" +#include "log/log.hpp" +#include + +namespace gui +{ + LogoWindow::LogoWindow(app::Application *app) : AppWindow(app, app::window::name::logo_window) + { + buildInterface(); + } + + void LogoWindow::rebuild() + { + destroyInterface(); + buildInterface(); + } + + void LogoWindow::buildInterface() + { + AppWindow::buildInterface(); + bottomBar->setVisible(false); + topBar->setVisible(false); + new gui::Image(this, 0, 0, 0, 0, "logo"); + } + + void LogoWindow::destroyInterface() + { + erase(); + } +} /* namespace gui */ diff --git a/module-apps/application-desktop/windows/LogoWindow.hpp b/module-apps/application-desktop/windows/LogoWindow.hpp new file mode 100644 index 0000000000000000000000000000000000000000..b3dcf1df3c916206d955b0b17db5a19661f4c7bd --- /dev/null +++ b/module-apps/application-desktop/windows/LogoWindow.hpp @@ -0,0 +1,19 @@ +// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved. +// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md + +#pragma once + +#include "AppWindow.hpp" + +namespace gui +{ + class LogoWindow : public AppWindow + { + public: + explicit LogoWindow(app::Application *app); + void rebuild() override; + void buildInterface() override; + void destroyInterface() override; + }; + +} /* namespace gui */ diff --git a/module-apps/application-desktop/windows/Names.hpp b/module-apps/application-desktop/windows/Names.hpp index 69ab224862d4d67fc5d0b9526629fd95d2eeaa24..f36f41a7019407a3dd74906d8eee1b98eba9b4df 100644 --- a/module-apps/application-desktop/windows/Names.hpp +++ b/module-apps/application-desktop/windows/Names.hpp @@ -11,6 +11,7 @@ namespace app::window::name inline constexpr auto desktop_reboot = "Reboot"; inline constexpr auto desktop_poweroff = "PowerOffWindow"; inline constexpr auto dead_battery = "DeadBatteryWindow"; + inline constexpr auto logo_window = "LogoWindow"; inline constexpr auto desktop_pin_lock = "PinLockWindow"; inline constexpr auto desktop_locked = "LockedInfoWindow"; inline constexpr auto desktop_update = "Update"; diff --git a/module-apps/application-desktop/windows/PowerOffWindow.cpp b/module-apps/application-desktop/windows/PowerOffWindow.cpp index 7643ac49aef3eb439e84cd10d7e3054c1ff2d981..75d9cd3a8148d9025b12ec05802ffdea7dfdc691 100644 --- a/module-apps/application-desktop/windows/PowerOffWindow.cpp +++ b/module-apps/application-desktop/windows/PowerOffWindow.cpp @@ -10,7 +10,6 @@ #include #include "PowerOffWindow.hpp" -#include "../ApplicationDesktop.hpp" // services #include @@ -18,11 +17,13 @@ #include "service-cellular/ServiceCellular.hpp" #include +#include namespace gui { - PowerOffWindow::PowerOffWindow(app::Application *app) : AppWindow(app, app::window::name::desktop_poweroff) + PowerOffWindow::PowerOffWindow(app::Application *app, std::unique_ptr &&presenter) + : AppWindow(app, app::window::name::desktop_poweroff), presenter(std::move(presenter)) { buildInterface(); } @@ -50,8 +51,6 @@ namespace gui bottomBar->setText(BottomBar::Side::RIGHT, utils::localize.get(style::strings::common::back)); powerImage = new gui::Image(this, 177, 132, 0, 0, "pin_lock_info"); - powerDownImage = new gui::Image(this, 0, 0, 0, 0, "logo"); - powerDownImage->setVisible(false); // title label titleLabel = new gui::Label(this, 0, 60, 480, 40); @@ -128,21 +127,10 @@ namespace gui }; selectionLabels[1]->activatedCallback = [=](gui::Item &item) { - LOG_INFO("Closing system"); - application->setShutdownFlag(); - - bottomBar->setVisible(false); - topBar->setVisible(false); - selectionLabels[0]->setVisible(false); - selectionLabels[1]->setVisible(false); - eventMgrLabel->setVisible(false); - powerImage->setVisible(false); - powerDownImage->setVisible(true); - titleLabel->setVisible(false); - infoLabel->setVisible(false); - - application->refreshWindow(RefreshModes::GUI_REFRESH_DEEP); - app::manager::Controller::sendAction(application, app::manager::actions::CloseSystem); + LOG_INFO("User call close system"); + + presenter->powerOff(); + return true; }; @@ -172,7 +160,6 @@ namespace gui infoLabel = nullptr; eventMgrLabel = nullptr; powerImage = nullptr; - powerDownImage = nullptr; selectionLabels.clear(); } diff --git a/module-apps/application-desktop/windows/PowerOffWindow.hpp b/module-apps/application-desktop/windows/PowerOffWindow.hpp index 510bc1ad73402e04bb8f8e62aab37a1ad789d1d4..4103d6107a9918723b71cc8162f69be57e9dfb42 100644 --- a/module-apps/application-desktop/windows/PowerOffWindow.hpp +++ b/module-apps/application-desktop/windows/PowerOffWindow.hpp @@ -8,6 +8,7 @@ #include "gui/widgets/Label.hpp" #include "gui/widgets/Image.hpp" #include "gui/widgets/BottomBar.hpp" +#include "../presenter/PowerOffPresenter.hpp" namespace gui { @@ -22,13 +23,14 @@ namespace gui gui::Label *titleLabel = nullptr; gui::Label *infoLabel = nullptr; + std::unique_ptr presenter; std::vector selectionLabels; gui::Label *eventMgrLabel = nullptr; gui::Image *powerImage = nullptr; gui::Image *powerDownImage = nullptr; State state = State::Return; public: - PowerOffWindow(app::Application *app); + PowerOffWindow(app::Application *app, std::unique_ptr &&presenter); void onBeforeShow(ShowMode mode, SwitchData *data) override; bool onInput(const InputEvent &inputEvent) override; diff --git a/module-apps/application-desktop/windows/Reboot.cpp b/module-apps/application-desktop/windows/Reboot.cpp index f3947a3966e9dc639a15f3826461f6b43f5f58ea..fd54b6da632cb0e79f0a72bfa0f67a49b8b78295 100644 --- a/module-apps/application-desktop/windows/Reboot.cpp +++ b/module-apps/application-desktop/windows/Reboot.cpp @@ -9,7 +9,8 @@ namespace gui { - RebootWindow::RebootWindow(app::Application *app) : AppWindow(app, app::window::name::desktop_reboot) + RebootWindow::RebootWindow(app::Application *app, std::unique_ptr &&presenter) + : AppWindow(app, app::window::name::desktop_reboot), presenter(std::move(presenter)) { buildInterface(); } @@ -58,12 +59,7 @@ namespace gui bool RebootWindow::onInput(const InputEvent &inputEvent) { - text->setText("!!! Shutdown !!!"); - application->refreshWindow(gui::RefreshModes::GUI_REFRESH_FAST); - /// needed to actually have time to show stuff on screen before system close - ulTaskNotifyTake(pdTRUE, 1000); - // shutdown - sys::SystemManager::CloseSystem(application); + presenter->powerOff(); return true; } diff --git a/module-apps/application-desktop/windows/Reboot.hpp b/module-apps/application-desktop/windows/Reboot.hpp index e9206cea6d58f9cf0a4cacef38e05f458a0871fc..a91089f8b381ef84e79f9f718d9fb831f85cd790 100644 --- a/module-apps/application-desktop/windows/Reboot.hpp +++ b/module-apps/application-desktop/windows/Reboot.hpp @@ -6,13 +6,14 @@ #include #include "AppWindow.hpp" #include +#include "../presenter/PowerOffPresenter.hpp" namespace gui { class RebootWindow : public AppWindow { public: - RebootWindow(app::Application *app); + RebootWindow(app::Application *app, std::unique_ptr &&presenter); ~RebootWindow() override = default; void onBeforeShow(ShowMode mode, SwitchData *data) override; bool onInput(const InputEvent &inputEvent) override; @@ -23,6 +24,7 @@ namespace gui private: void invalidate() noexcept; + std::unique_ptr presenter; Text *text = nullptr; }; diff --git a/module-services/service-antenna/ServiceAntenna.cpp b/module-services/service-antenna/ServiceAntenna.cpp index 80f7eb3fa1b49ecb9fc3047325baca6c92487ee8..2085dbe9330cfcc0240a8919a3ab7d7312020ffa 100644 --- a/module-services/service-antenna/ServiceAntenna.cpp +++ b/module-services/service-antenna/ServiceAntenna.cpp @@ -175,6 +175,11 @@ sys::ReturnCodes ServiceAntenna::DeinitHandler() return sys::ReturnCodes::Success; } +void ServiceAntenna::ProcessCloseReason(sys::CloseReason closeReason) +{ + sendCloseReadyMessage(this); +} + sys::ReturnCodes ServiceAntenna::SwitchPowerModeHandler(const sys::ServicePowerMode mode) { LOG_FATAL("[ServiceEvtMgr] PowerModeHandler: %s", c_str(mode)); diff --git a/module-services/service-antenna/service-antenna/ServiceAntenna.hpp b/module-services/service-antenna/service-antenna/ServiceAntenna.hpp index 4717759a77567d23da269ed7c4857b6c22d3afe8..414c39d6aa62799a83bcbd19e84c8eef1a0b66cd 100644 --- a/module-services/service-antenna/service-antenna/ServiceAntenna.hpp +++ b/module-services/service-antenna/service-antenna/ServiceAntenna.hpp @@ -92,6 +92,8 @@ class ServiceAntenna : public sys::Service sys::ReturnCodes DeinitHandler() override; + void ProcessCloseReason(sys::CloseReason closeReason) override; + sys::ReturnCodes SwitchPowerModeHandler(const sys::ServicePowerMode mode) override final; void storeCurrentState(void); diff --git a/module-services/service-appmgr/model/ApplicationManager.cpp b/module-services/service-appmgr/model/ApplicationManager.cpp index d540f79a3812443755c5dfecc24da86d8fc75c9b..91cb4a6d2ae51653a5ef67af9032948686719727 100644 --- a/module-services/service-appmgr/model/ApplicationManager.cpp +++ b/module-services/service-appmgr/model/ApplicationManager.cpp @@ -37,10 +37,7 @@ namespace app::manager { namespace { - constexpr auto shutdown_delay_ms = 500; - constexpr auto timerBlock = "BlockTimer"; - constexpr auto timerShutdownDelay = "ShutdownDelay"; } // namespace ApplicationManagerBase::ApplicationManagerBase(std::vector> &&launchers) @@ -111,7 +108,6 @@ namespace app::manager this, std::numeric_limits::max(), sys::Timer::Type::SingleShot)}, - shutdownDelay{std::make_unique(timerShutdownDelay, this, shutdown_delay_ms)}, settings(std::make_unique(this)), phoneModeObserver(std::make_unique()) { @@ -189,10 +185,25 @@ namespace app::manager { settings->unregisterValueChange(); closeApplications(); - closeServices(); return sys::ReturnCodes::Success; } + auto ApplicationManager::ProcessCloseReason(sys::CloseReason closeReason) -> void + { + ActionRequest act = ActionRequest{this->GetName(), app::manager::actions::DisplayLogoAtExit, nullptr}; + switch (closeReason) { + case sys::CloseReason::SystemBrownout: + act = ActionRequest{this->GetName(), app::manager::actions::SystemBrownout, nullptr}; + break; + case sys::CloseReason::RegularPowerDown: + break; + case sys::CloseReason::Reboot: + break; + } + handleActionRequest(&act); + sendCloseReadyMessage(this); + } + auto ApplicationManager::DataReceivedHandler([[maybe_unused]] sys::DataMessage *msgl, [[maybe_unused]] sys::ResponseMessage *resp) -> sys::MessagePointer { @@ -284,7 +295,6 @@ namespace app::manager }); connect(typeid(ShutdownRequest), [this](sys::Message *) { closeApplications(); - closeServices(); return std::make_shared(); }); connect(typeid(ActionRequest), [this](sys::Message *request) { @@ -323,7 +333,6 @@ namespace app::manager connect(typeid(CellularNoSimNotification), convertibleToActionHandler); connect(typeid(CellularNotAnEmergencyNotification), convertibleToActionHandler); connect(typeid(sys::CriticalBatteryLevelNotification), convertibleToActionHandler); - connect(typeid(sys::SystemBrownoutMesssage), convertibleToActionHandler); connect(typeid(CellularSmsNoSimRequestMessage), convertibleToActionHandler); connect(typeid(sdesktop::passcode::ScreenPasscodeRequest), convertibleToActionHandler); } @@ -360,13 +369,6 @@ namespace app::manager return true; } - auto ApplicationManager::closeServices() -> bool - { - closeService(service::name::gui); - closeService(service::name::eink); - return true; - } - auto ApplicationManager::closeApplications() -> bool { for (const auto &app : getApplications()) { @@ -398,7 +400,7 @@ namespace app::manager void ApplicationManager::closeService(const std::string &name) { - bool ret = sys::SystemManager::DestroyService(name, this); + bool ret = sys::SystemManager::DestroyApplication(name, this); if (ret) { LOG_INFO("Service/Application %s closed", name.c_str()); } @@ -490,8 +492,6 @@ namespace app::manager return handleHomeAction(action); case actions::Launch: return handleLaunchAction(action); - case actions::CloseSystem: - return handleCloseSystem(); default: return handleCustomAction(action); } @@ -517,14 +517,6 @@ namespace app::manager return handleSwitchApplication(&switchRequest); } - auto ApplicationManager::handleCloseSystem() -> bool - { - shutdownDelay->connect([&](sys::Timer &) { sys::SystemManager::CloseSystem(this); }); - shutdownDelay->start(); - - return true; - } - auto ApplicationManager::handleCustomAction(ActionEntry &action) -> bool { const auto actionHandlers = applications.findByAction(action.actionId); diff --git a/module-services/service-appmgr/service-appmgr/Actions.hpp b/module-services/service-appmgr/service-appmgr/Actions.hpp index ebf3e7268bfb628ff91f020bd01dec03bd8f437e..f9aca42a3d3100e4a393130bcf41d7f6be8905cd 100644 --- a/module-services/service-appmgr/service-appmgr/Actions.hpp +++ b/module-services/service-appmgr/service-appmgr/Actions.hpp @@ -25,7 +25,6 @@ namespace app::manager Home, AutoLock, Launch, - CloseSystem, Call, NotAnEmergencyNotification, NoSimNotification, @@ -56,6 +55,7 @@ namespace app::manager DisplayLowBatteryNotification, SystemBrownout, RequestScreenPasscode, + DisplayLogoAtExit, UserAction // The last enumerator in the Action enum. // All user-defined actions shall have values greater than UserAction. // All system-wide actions shall have values lesser than UserAction. diff --git a/module-services/service-appmgr/service-appmgr/messages/UserPowerDownRequest.hpp b/module-services/service-appmgr/service-appmgr/messages/UserPowerDownRequest.hpp new file mode 100644 index 0000000000000000000000000000000000000000..53408cc4a60da909f1f42f2590d67887cfdca265 --- /dev/null +++ b/module-services/service-appmgr/service-appmgr/messages/UserPowerDownRequest.hpp @@ -0,0 +1,13 @@ +// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved. +// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md + +#pragma once + +#include "BaseMessage.hpp" + +namespace app +{ + class UserPowerDownRequest : public sys::Message + {}; + +} // namespace app diff --git a/module-services/service-appmgr/service-appmgr/model/ApplicationManager.hpp b/module-services/service-appmgr/service-appmgr/model/ApplicationManager.hpp index 5e3c8417713e50703dfada925ce810add51b17da..117d14e398baa8cd3c6c4fb376730ea7e2ba382e 100644 --- a/module-services/service-appmgr/service-appmgr/model/ApplicationManager.hpp +++ b/module-services/service-appmgr/service-appmgr/model/ApplicationManager.hpp @@ -100,6 +100,7 @@ namespace app::manager auto InitHandler() -> sys::ReturnCodes override; auto DeinitHandler() -> sys::ReturnCodes override; + auto ProcessCloseReason(sys::CloseReason closeReason) -> void override; auto SwitchPowerModeHandler(const sys::ServicePowerMode mode) -> sys::ReturnCodes override; auto DataReceivedHandler(sys::DataMessage *msgl, sys::ResponseMessage *resp) -> sys::MessagePointer override; @@ -108,7 +109,6 @@ namespace app::manager void startBackgroundApplications(); void rebuildActiveApplications(); void suspendSystemServices(); - auto closeServices() -> bool; auto closeApplications() -> bool; auto closeApplicationsOnUpdate() -> bool; void closeService(const std::string &name); @@ -120,7 +120,6 @@ namespace app::manager void handleActionRequest(ActionRequest *actionMsg); auto handleHomeAction(ActionEntry &action) -> bool; auto handleLaunchAction(ActionEntry &action) -> bool; - auto handleCloseSystem() -> bool; auto handleCustomAction(ActionEntry &action) -> bool; auto handleSwitchApplication(SwitchRequest *msg, bool closeCurrentlyFocusedApp = true) -> bool; auto handleCloseConfirmation(CloseConfirmation *msg) -> bool; @@ -166,7 +165,6 @@ namespace app::manager // If it reaches time defined in settings database application // manager is sending signal to Application Desktop in order to // lock screen. - std::unique_ptr shutdownDelay; std::unique_ptr settings; std::unique_ptr phoneModeObserver; void displayLanguageChanged(std::string value); diff --git a/module-services/service-audio/ServiceAudio.cpp b/module-services/service-audio/ServiceAudio.cpp index a48aa9806d85099e724e02e359eae99ed4588ee1..52e93f14d45fe6943c100ba1b1d1ce131a3c659f 100644 --- a/module-services/service-audio/ServiceAudio.cpp +++ b/module-services/service-audio/ServiceAudio.cpp @@ -179,6 +179,11 @@ sys::ReturnCodes ServiceAudio::DeinitHandler() return sys::ReturnCodes::Success; } +void ServiceAudio::ProcessCloseReason(sys::CloseReason closeReason) +{ + sendCloseReadyMessage(this); +} + std::optional ServiceAudio::AudioServicesCallback(const sys::Message *msg) { if (const auto *eof = dynamic_cast(msg); eof) { diff --git a/module-services/service-audio/service-audio/ServiceAudio.hpp b/module-services/service-audio/service-audio/ServiceAudio.hpp index 4be865d47534ac0171471ff78f0eeb367722a734..0fdf35185cf6d306ecf54f953fe0fcac832346ab 100644 --- a/module-services/service-audio/service-audio/ServiceAudio.hpp +++ b/module-services/service-audio/service-audio/ServiceAudio.hpp @@ -42,6 +42,8 @@ class ServiceAudio : public sys::Service sys::ReturnCodes DeinitHandler() override; + void ProcessCloseReason(sys::CloseReason closeReason) override; + sys::ReturnCodes SwitchPowerModeHandler(const sys::ServicePowerMode mode) override final; private: diff --git a/module-services/service-bluetooth/ServiceBluetooth.cpp b/module-services/service-bluetooth/ServiceBluetooth.cpp index 278cf6a9b59c25effd29499718467c34fcbe5aec..80d76defd154a55b3aa9f79f0e5b2c63a8b379af 100644 --- a/module-services/service-bluetooth/ServiceBluetooth.cpp +++ b/module-services/service-bluetooth/ServiceBluetooth.cpp @@ -176,6 +176,11 @@ sys::ReturnCodes ServiceBluetooth::DeinitHandler() return sys::ReturnCodes::Success; } +void ServiceBluetooth::ProcessCloseReason(sys::CloseReason closeReason) +{ + sendCloseReadyMessage(this); +} + sys::MessagePointer ServiceBluetooth::DataReceivedHandler(sys::DataMessage *msg, sys::ResponseMessage *resp) { try { diff --git a/module-services/service-bluetooth/service-bluetooth/ServiceBluetooth.hpp b/module-services/service-bluetooth/service-bluetooth/ServiceBluetooth.hpp index 246928bb46ef8990ed100b5c9ed021197aca538c..d2200477046a795d5b277cbfa663af74af565fe5 100644 --- a/module-services/service-bluetooth/service-bluetooth/ServiceBluetooth.hpp +++ b/module-services/service-bluetooth/service-bluetooth/ServiceBluetooth.hpp @@ -33,6 +33,7 @@ class ServiceBluetooth : public sys::Service virtual sys::MessagePointer DataReceivedHandler(sys::DataMessage *msg, sys::ResponseMessage *resp) override; sys::ReturnCodes InitHandler() override; sys::ReturnCodes DeinitHandler() override; + void ProcessCloseReason(sys::CloseReason closeReason) override; virtual sys::ReturnCodes SwitchPowerModeHandler(const sys::ServicePowerMode mode) override; void sendWorkerCommand(bluetooth::Command command); QueueHandle_t workerQueue = nullptr; diff --git a/module-services/service-cellular/ServiceCellular.cpp b/module-services/service-cellular/ServiceCellular.cpp index 839985c1cfe1f177c63357734bf1b8229928b47e..258c05ff069b031d9c9664d6da24835adcf782bb 100644 --- a/module-services/service-cellular/ServiceCellular.cpp +++ b/module-services/service-cellular/ServiceCellular.cpp @@ -270,10 +270,14 @@ sys::ReturnCodes ServiceCellular::InitHandler() sys::ReturnCodes ServiceCellular::DeinitHandler() { - return sys::ReturnCodes::Success; } +void ServiceCellular::ProcessCloseReason(sys::CloseReason closeReason) +{ + sendCloseReadyMessage(this); +} + sys::ReturnCodes ServiceCellular::SwitchPowerModeHandler(const sys::ServicePowerMode mode) { LOG_FATAL("[ServiceCellular] PowerModeHandler: %s", c_str(mode)); diff --git a/module-services/service-cellular/service-cellular/ServiceCellular.hpp b/module-services/service-cellular/service-cellular/ServiceCellular.hpp index db5ed8c9b8b5cf6c6c087b404eee28096c6320a2..043a165e5000ec39da802167c6b5c81370946620 100644 --- a/module-services/service-cellular/service-cellular/ServiceCellular.hpp +++ b/module-services/service-cellular/service-cellular/ServiceCellular.hpp @@ -72,6 +72,7 @@ class ServiceCellular : public sys::Service // Invoked during initialization sys::ReturnCodes InitHandler() override; sys::ReturnCodes DeinitHandler() override; + void ProcessCloseReason(sys::CloseReason closeReason) override; sys::ReturnCodes SwitchPowerModeHandler(const sys::ServicePowerMode mode) override final; /** Register message handlers. diff --git a/module-services/service-db/ServiceDB.cpp b/module-services/service-db/ServiceDB.cpp index 758550d40921594d7b1d3d9792ea2da4310e34fe..0fdc58b258554c0a59da41fbbf540c6f95efd79a 100644 --- a/module-services/service-db/ServiceDB.cpp +++ b/module-services/service-db/ServiceDB.cpp @@ -563,6 +563,11 @@ sys::ReturnCodes ServiceDB::DeinitHandler() return sys::ReturnCodes::Success; } +void ServiceDB::ProcessCloseReason(sys::CloseReason closeReason) +{ + sendCloseReadyMessage(this); +} + sys::ReturnCodes ServiceDB::SwitchPowerModeHandler(const sys::ServicePowerMode mode) { LOG_FATAL("[%s] PowerModeHandler: %s", this->GetName().c_str(), c_str(mode)); diff --git a/module-services/service-db/ServiceDB.hpp b/module-services/service-db/ServiceDB.hpp index 57226d347e68441f1a21b3967fe4dd8394235f82..8b4f2479b412263d59dd959396d8ffb8723f75b4 100644 --- a/module-services/service-db/ServiceDB.hpp +++ b/module-services/service-db/ServiceDB.hpp @@ -89,6 +89,8 @@ class ServiceDB : public sys::Service sys::ReturnCodes DeinitHandler() override; + void ProcessCloseReason(sys::CloseReason closeReason) override; + sys::ReturnCodes SwitchPowerModeHandler(const sys::ServicePowerMode mode) final; bool StoreIntoBackup(const std::filesystem::path &backupPath); diff --git a/module-services/service-db/test/test-settings/test-service-db-settings-api.cpp b/module-services/service-db/test/test-settings/test-service-db-settings-api.cpp index 0f181d095d16f4d15645cd65307285d102ae4ef1..f2c4d20ae450f85561942bc15a5e751d7ba731c8 100644 --- a/module-services/service-db/test/test-settings/test-service-db-settings-api.cpp +++ b/module-services/service-db/test/test-settings/test-service-db-settings-api.cpp @@ -52,38 +52,38 @@ TEST_CASE("SettingsApi") testStart = std::make_shared(); testStart->lock(); std::cout << "start thr_id: " << std::this_thread::get_id() << std::endl << std::flush; - auto ret = sys::SystemManager::RunService(std::make_shared(service::name::evt_manager), - manager.get()); - ret &= sys::SystemManager::RunService(std::make_shared(), manager.get()); + auto ret = sys::SystemManager::RunSystemService( + std::make_shared(service::name::evt_manager), manager.get()); + ret &= sys::SystemManager::RunSystemService(std::make_shared(), manager.get()); varWritter = std::make_shared("writterVar"); varReader = std::make_shared("readerVar"); - ret &= sys::SystemManager::RunService(varWritter, manager.get()); - ret &= sys::SystemManager::RunService(varReader, manager.get()); + ret &= sys::SystemManager::RunSystemService(varWritter, manager.get()); + ret &= sys::SystemManager::RunSystemService(varReader, manager.get()); testVar = std::make_shared("appTest", varWritter, varReader, testStart); - ret &= sys::SystemManager::RunService(testVar, manager.get()); + ret &= sys::SystemManager::RunSystemService(testVar, manager.get()); profWritter = std::make_shared("writterProf"); profReader = std::make_shared("readerProf"); - ret &= sys::SystemManager::RunService(profWritter, manager.get()); - ret &= sys::SystemManager::RunService(profReader, manager.get()); + ret &= sys::SystemManager::RunSystemService(profWritter, manager.get()); + ret &= sys::SystemManager::RunSystemService(profReader, manager.get()); testProf = std::make_shared( "appTestProfile", profWritter, profReader, testStart); - ret &= sys::SystemManager::RunService(testProf, manager.get()); + ret &= sys::SystemManager::RunSystemService(testProf, manager.get()); modeWritter = std::make_shared("writterMode"); modeReader = std::make_shared("readerMode"); - ret &= sys::SystemManager::RunService(modeWritter, manager.get()); - ret &= sys::SystemManager::RunService(modeReader, manager.get()); + ret &= sys::SystemManager::RunSystemService(modeWritter, manager.get()); + ret &= sys::SystemManager::RunSystemService(modeReader, manager.get()); testMode = std::make_shared("appTestMode", modeWritter, modeReader, testStart); - ret &= sys::SystemManager::RunService(testMode, manager.get()); + ret &= sys::SystemManager::RunSystemService(testMode, manager.get()); std::cout << "koniec start thr_id: " << std::this_thread::get_id() << std::endl << std::flush; testStart->unlock(); diff --git a/module-services/service-db/test/test-settings/test-service-db-settings-testapps.hpp b/module-services/service-db/test/test-settings/test-service-db-settings-testapps.hpp index 1e56890e359a65b3e2c2b57e4b9aa4fb035c2a8d..b6afb19af06c155eb3ae7fce45f06a6ec73214bf 100644 --- a/module-services/service-db/test/test-settings/test-service-db-settings-testapps.hpp +++ b/module-services/service-db/test/test-settings/test-service-db-settings-testapps.hpp @@ -1,6 +1,11 @@ // Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved. // For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md +namespace app +{ + class UserPowerDownRequest : public sys::Message + {}; +} // namespace app namespace settings { class TestService : public sys::Service @@ -84,7 +89,7 @@ namespace settings testStart->lock(); testStart->unlock(); if (state != State::Unk) { - sys::SystemManager::CloseSystem(this); + closeSystem(); } else { state = State::Start; @@ -133,12 +138,19 @@ namespace settings } else if (nullptr != dynamic_cast(msg)) { if (state == State::Unregister) { - sys::SystemManager::CloseSystem(this); + closeSystem(); } } return std::make_shared(); } + + protected: + void closeSystem() + { + auto msg = std::make_shared(); + bus.sendUnicast(std::move(msg), service::name::system_manager); + } }; class AppTestProfileMode : public AppTest @@ -157,7 +169,7 @@ namespace settings testStart->lock(); testStart->unlock(); if (state != State::Unk) { - sys::SystemManager::CloseSystem(this); + closeSystem(); } else { state = State::Start; @@ -234,7 +246,7 @@ namespace settings } else if (nullptr != dynamic_cast(msg)) { if (state == State::RegisterAllAdd) { - sys::SystemManager::CloseSystem(this); + closeSystem(); } } diff --git a/module-services/service-desktop/ServiceDesktop.cpp b/module-services/service-desktop/ServiceDesktop.cpp index b9e7e4d079b24904a4ead81dfd85f633f352334b..7b857128e27ecf393ae342ab56886dc3c4ced686 100644 --- a/module-services/service-desktop/ServiceDesktop.cpp +++ b/module-services/service-desktop/ServiceDesktop.cpp @@ -236,6 +236,11 @@ sys::ReturnCodes ServiceDesktop::DeinitHandler() return sys::ReturnCodes::Success; } +void ServiceDesktop::ProcessCloseReason(sys::CloseReason closeReason) +{ + sendCloseReadyMessage(this); +} + sys::ReturnCodes ServiceDesktop::SwitchPowerModeHandler(const sys::ServicePowerMode mode) { return sys::ReturnCodes::Success; diff --git a/module-services/service-desktop/endpoints/backup/BackupRestore.cpp b/module-services/service-desktop/endpoints/backup/BackupRestore.cpp index 06b71b790c890ff34fb882e3a9e90fd00e033b85..4e3e260b351efe241c3262641916f41e5f5d1041 100644 --- a/module-services/service-desktop/endpoints/backup/BackupRestore.cpp +++ b/module-services/service-desktop/endpoints/backup/BackupRestore.cpp @@ -137,7 +137,7 @@ void BackupRestore::RestoreUserFiles(sys::Service *ownerService) /* close user files to be restored */ LOG_INFO("RestoreUserFiles: closing ServiceDB..."); std::string dbServiceName = service::name::db; - sys::SystemManager::DestroyService(dbServiceName, ownerService); + sys::SystemManager::DestroySystemService(dbServiceName, ownerService); BackupRestore::ReplaceUserFiles(); diff --git a/module-services/service-desktop/endpoints/factoryReset/FactoryReset.cpp b/module-services/service-desktop/endpoints/factoryReset/FactoryReset.cpp index 242927582f5a0d351e94377dc1e413794f68f37b..416e07dfe81a143d891e4bf4d2dfc5d246c0caf3 100644 --- a/module-services/service-desktop/endpoints/factoryReset/FactoryReset.cpp +++ b/module-services/service-desktop/endpoints/factoryReset/FactoryReset.cpp @@ -52,7 +52,7 @@ namespace FactoryReset if (ownerService != nullptr) { LOG_INFO("FactoryReset: closing ServiceDB..."); std::string dbServiceName = service::name::db; - sys::SystemManager::DestroyService(dbServiceName, ownerService); + sys::SystemManager::DestroySystemService(dbServiceName, ownerService); } if (DeleteDirContent(purefs::dir::getRootDiskPath()) != true) { diff --git a/module-services/service-desktop/service-desktop/ServiceDesktop.hpp b/module-services/service-desktop/service-desktop/ServiceDesktop.hpp index 0d17b4026faf62678b4f14910d7a4d886c5f1a71..1510c085f02e3e7fd20edbe1434975987cd3cdfe 100644 --- a/module-services/service-desktop/service-desktop/ServiceDesktop.hpp +++ b/module-services/service-desktop/service-desktop/ServiceDesktop.hpp @@ -56,6 +56,7 @@ class ServiceDesktop : public sys::Service sys::ReturnCodes InitHandler() override; sys::ReturnCodes DeinitHandler() override; + void ProcessCloseReason(sys::CloseReason closeReason) override; sys::ReturnCodes SwitchPowerModeHandler(const sys::ServicePowerMode mode) override; sys::MessagePointer DataReceivedHandler(sys::DataMessage *msg, sys::ResponseMessage *resp) override; diff --git a/module-services/service-eink/ServiceEink.cpp b/module-services/service-eink/ServiceEink.cpp index 4e7d143e7a8ea352f50e64aaa48d86fb2886a9cf..c0c5d07301ad757b027dbcd9a2678aef845c5592 100644 --- a/module-services/service-eink/ServiceEink.cpp +++ b/module-services/service-eink/ServiceEink.cpp @@ -81,6 +81,11 @@ namespace service::eink return sys::ReturnCodes::Success; } + void ServiceEink::ProcessCloseReason(sys::CloseReason closeReason) + { + sendCloseReadyMessage(this); + } + sys::ReturnCodes ServiceEink::SwitchPowerModeHandler(const sys::ServicePowerMode mode) { LOG_INFO("PowerModeHandler: %s", c_str(mode)); diff --git a/module-services/service-eink/ServiceEink.hpp b/module-services/service-eink/ServiceEink.hpp index f08282da5cea05ef3542a86350206e68b3a64443..987fe4eec1686f250af9e66344b2f7c565a50e51 100644 --- a/module-services/service-eink/ServiceEink.hpp +++ b/module-services/service-eink/ServiceEink.hpp @@ -28,6 +28,7 @@ namespace service::eink sys::MessagePointer DataReceivedHandler(sys::DataMessage *msgl, sys::ResponseMessage *response) override; sys::ReturnCodes InitHandler() override; sys::ReturnCodes DeinitHandler() override; + void ProcessCloseReason(sys::CloseReason closeReason) override; sys::ReturnCodes SwitchPowerModeHandler(const sys::ServicePowerMode mode) override; private: diff --git a/module-services/service-evtmgr/EventManager.cpp b/module-services/service-evtmgr/EventManager.cpp index d4d9ba133c40e1a91f6d026b2fbf4fc4a1f9c65b..16665cb42c044edadf8180ec9b1da8b5ef0fdfd3 100644 --- a/module-services/service-evtmgr/EventManager.cpp +++ b/module-services/service-evtmgr/EventManager.cpp @@ -324,6 +324,11 @@ sys::ReturnCodes EventManager::DeinitHandler() return sys::ReturnCodes::Success; } +void EventManager::ProcessCloseReason(sys::CloseReason closeReason) +{ + sendCloseReadyMessage(this); +} + sys::ReturnCodes EventManager::SwitchPowerModeHandler(const sys::ServicePowerMode mode) { LOG_FATAL("[ServiceEvtMgr] PowerModeHandler: %s", c_str(mode)); diff --git a/module-services/service-evtmgr/service-evtmgr/EventManager.hpp b/module-services/service-evtmgr/service-evtmgr/EventManager.hpp index 02fd39ffb8f19f8b732e6a2faec8ec3e87f1420f..f19df6292df975893f64ddaedf65b3863247a20a 100644 --- a/module-services/service-evtmgr/service-evtmgr/EventManager.hpp +++ b/module-services/service-evtmgr/service-evtmgr/EventManager.hpp @@ -63,6 +63,8 @@ class EventManager : public sys::Service sys::ReturnCodes DeinitHandler() override; + void ProcessCloseReason(sys::CloseReason closeReason) override; + sys::ReturnCodes SwitchPowerModeHandler(const sys::ServicePowerMode mode) override final; /** diff --git a/module-services/service-fota/ServiceFota.cpp b/module-services/service-fota/ServiceFota.cpp index 7b57b26cee8260efba9dd9f768da723cb56f5209..e2e3540f5a57c995f32897b9fe3ef6f6f587f352 100644 --- a/module-services/service-fota/ServiceFota.cpp +++ b/module-services/service-fota/ServiceFota.cpp @@ -71,6 +71,11 @@ namespace FotaService return sys::ReturnCodes::Success; } + void Service::ProcessCloseReason(sys::CloseReason closeReason) + { + sendCloseReadyMessage(this); + } + void Service::registerMessageHandlers() { LOG_DEBUG("Registring Handlers for Fota::Service:"); diff --git a/module-services/service-fota/service-fota/ServiceFota.hpp b/module-services/service-fota/service-fota/ServiceFota.hpp index 76fd520e5cd3cecf73244fec255f2d4927b0bd2c..1dd459c0bbf20e00ad021856c9636f9a9c79e335 100644 --- a/module-services/service-fota/service-fota/ServiceFota.hpp +++ b/module-services/service-fota/service-fota/ServiceFota.hpp @@ -60,6 +60,8 @@ namespace FotaService sys::ReturnCodes DeinitHandler() override; + void ProcessCloseReason(sys::CloseReason closeReason) override; + sys::ReturnCodes SwitchPowerModeHandler(const sys::ServicePowerMode /*mode*/) override final { return sys::ReturnCodes::Success; diff --git a/module-services/service-gui/ServiceGUI.cpp b/module-services/service-gui/ServiceGUI.cpp index 599b923c7afb8ee1c7aca55f4da68d1890e95c29..f2c85a97d11aa1152ae5d1d3065dc07caaad8671 100644 --- a/module-services/service-gui/ServiceGUI.cpp +++ b/module-services/service-gui/ServiceGUI.cpp @@ -39,7 +39,7 @@ namespace service::gui CommandsQueueCapacity)}, contextReleaseTimer{ std::make_unique(this, ContextReleaseTimeout.count(), sys::Timer::Type::SingleShot)}, - currentState{State::NotInitialised} + currentState{State::NotInitialised}, lastRenderScheduled{false}, waitingForLastRender{false} { initAssetManagers(); registerMessageHandlers(); @@ -94,6 +94,11 @@ namespace service::gui return sys::ReturnCodes::Success; } + void ServiceGUI::ProcessCloseReason(sys::CloseReason closeReason) + { + waitingForLastRender = true; + } + sys::ReturnCodes ServiceGUI::SwitchPowerModeHandler(const sys::ServicePowerMode mode) { LOG_INFO("PowerModeHandler: %s", c_str(mode)); @@ -114,24 +119,26 @@ namespace service::gui { if (isInState(State::NotInitialised)) { LOG_WARN("Service not yet initialised - ignoring draw commands"); - return sys::MessageNone{}; + return std::make_shared(sys::ReturnCodes::Unresolved); } - if (isInState(State::Suspended)) { - LOG_WARN("Suspended - ignoring draw commands"); - return sys::MessageNone{}; + if (isInState(State::Suspended) || lastRenderScheduled) { + LOG_WARN("Ignoring draw commands"); + return std::make_shared(sys::ReturnCodes::Unresolved); } if (const auto drawMsg = static_cast(message); !drawMsg->commands.empty()) { - if (drawMsg->isType(DrawMessage::Type::SHUTDOWN) || drawMsg->isType(DrawMessage::Type::SUSPEND)) { + if (drawMsg->isType(DrawMessage::Type::SUSPEND)) { setState(State::Suspended); } - + else if (drawMsg->isType(DrawMessage::Type::SHUTDOWN)) { + lastRenderScheduled = true; + } if (!isAnyFrameBeingRenderedOrDisplayed()) { prepareDisplayEarly(drawMsg->mode); } notifyRenderer(std::move(drawMsg->commands), drawMsg->mode); } - return sys::MessageNone{}; + return std::make_shared(); } sys::MessagePointer ServiceGUI::handleChangeColorScheme(sys::Message *message) @@ -242,6 +249,10 @@ namespace service::gui if (isNextFrameReady() and not isAnyFrameBeingRenderedOrDisplayed()) { trySendNextFrame(); } + else if (lastRenderScheduled && waitingForLastRender) { + sendCloseReadyMessage(this); + } + return sys::MessageNone{}; } diff --git a/module-services/service-gui/ServiceGUI.hpp b/module-services/service-gui/ServiceGUI.hpp index 6c4e7d22080cfbd6741c1b151864bf42971dde04..74df40aaa38c83f029736c6ba5e42c0726955896 100644 --- a/module-services/service-gui/ServiceGUI.hpp +++ b/module-services/service-gui/ServiceGUI.hpp @@ -41,6 +41,7 @@ namespace service::gui sys::ReturnCodes InitHandler() override; sys::ReturnCodes DeinitHandler() override; + void ProcessCloseReason(sys::CloseReason closeReason) override; sys::MessagePointer DataReceivedHandler(sys::DataMessage *msgl, sys::ResponseMessage *resp) override; sys::ReturnCodes SwitchPowerModeHandler(const sys::ServicePowerMode mode) override; @@ -90,6 +91,8 @@ namespace service::gui std::optional cachedRender; std::unique_ptr contextReleaseTimer; State currentState; + bool lastRenderScheduled; + bool waitingForLastRender; }; } // namespace service::gui diff --git a/module-services/service-lwip/ServiceLwIP.cpp b/module-services/service-lwip/ServiceLwIP.cpp index 55aa3027a3b7cdf9eb5812dd70e9dab07d2462c4..64c75c7e68f81dc9c093956951c6da313c76bc66 100644 --- a/module-services/service-lwip/ServiceLwIP.cpp +++ b/module-services/service-lwip/ServiceLwIP.cpp @@ -72,6 +72,11 @@ sys::ReturnCodes ServiceLwIP::DeinitHandler() return sys::ReturnCodes::Success; } +void ServiceLwIP::ProcessCloseReason(sys::CloseReason closeReason) +{ + sendCloseReadyMessage(this); +} + sys::MessagePointer ServiceLwIP::DataReceivedHandler(sys::DataMessage *msg, sys::ResponseMessage *resp) { LOG_ERROR("TRY START LWIP"); diff --git a/module-services/service-lwip/service-lwip/ServiceLwIP.hpp b/module-services/service-lwip/service-lwip/ServiceLwIP.hpp index 40b675a0e97552fd751852b12ea8104d3e38dccb..db468bf6a15561418a9dd314dfbef68116fd7c5a 100644 --- a/module-services/service-lwip/service-lwip/ServiceLwIP.hpp +++ b/module-services/service-lwip/service-lwip/ServiceLwIP.hpp @@ -44,6 +44,7 @@ class ServiceLwIP : public sys::Service virtual sys::MessagePointer DataReceivedHandler(sys::DataMessage *msg, sys::ResponseMessage *resp) override; sys::ReturnCodes InitHandler() override; sys::ReturnCodes DeinitHandler() override; + void ProcessCloseReason(sys::CloseReason closeReason) override; virtual sys::ReturnCodes SwitchPowerModeHandler(const sys::ServicePowerMode mode) override; }; diff --git a/module-services/service-time/ServiceTime.cpp b/module-services/service-time/ServiceTime.cpp index 9a2b29127c5f4071ade73cff5db11161909be389..4f2481a7f65235f01cc0f8c323aa85f49015000b 100644 --- a/module-services/service-time/ServiceTime.cpp +++ b/module-services/service-time/ServiceTime.cpp @@ -40,6 +40,11 @@ namespace stm return sys::ReturnCodes::Success; } + void ServiceTime::ProcessCloseReason(sys::CloseReason closeReason) + { + sendCloseReadyMessage(this); + } + sys::ReturnCodes ServiceTime::SwitchPowerModeHandler(const sys::ServicePowerMode mode) { LOG_FATAL("[ServiceTime] PowerModeHandler: %s", c_str(mode)); diff --git a/module-services/service-time/ServiceTime.hpp b/module-services/service-time/ServiceTime.hpp index 19edc0984be2b685916ea5852fba0cf4a1c9ea9a..8a842cfb93f03d4fc193ca2fed69604c48480a29 100644 --- a/module-services/service-time/ServiceTime.hpp +++ b/module-services/service-time/ServiceTime.hpp @@ -38,6 +38,7 @@ namespace stm sys::ReturnCodes InitHandler() override; sys::ReturnCodes DeinitHandler() override; + void ProcessCloseReason(sys::CloseReason closeReason) override; sys::ReturnCodes SwitchPowerModeHandler(const sys::ServicePowerMode mode) override final; sys::MessagePointer DataReceivedHandler(sys::DataMessage *msgl, sys::ResponseMessage *resp = nullptr) override; diff --git a/module-sys/Service/Common.hpp b/module-sys/Service/Common.hpp index 6406e93dd037665c15fda6490a3406fdff062b36..9af38216b1305fe66571c886d6f2b511e3883193 100644 --- a/module-sys/Service/Common.hpp +++ b/module-sys/Service/Common.hpp @@ -41,6 +41,14 @@ namespace sys SuspendToRAM, SuspendToNVM }; + + enum class CloseReason + { + RegularPowerDown, + Reboot, + SystemBrownout + }; + } // namespace sys inline const char *c_str(sys::ReturnCodes code) diff --git a/module-sys/Service/Message.cpp b/module-sys/Service/Message.cpp index aa49f9db8113c976840cb9039b882dfbe9bf1c2d..4fde7d961f6ffacb92a84dab4e6e19f954baaf6f 100644 --- a/module-sys/Service/Message.cpp +++ b/module-sys/Service/Message.cpp @@ -30,6 +30,20 @@ namespace sys return Proxy::handleSystemMessage(service, this); } + ServiceCloseReasonMessage::ServiceCloseReasonMessage(CloseReason closeReason) : closeReason(closeReason) + {} + + MessagePointer ServiceCloseReasonMessage::Execute(Service *service) + { + Proxy::handleCloseReasonMessage(service, this); + return MessageNone{}; + } + + CloseReason ServiceCloseReasonMessage::getCloseReason() const noexcept + { + return closeReason; + } + DataMessage::DataMessage(MessageType messageType) : messageType{messageType} { type = Type::Data; diff --git a/module-sys/Service/Message.hpp b/module-sys/Service/Message.hpp index faa2e03296c4624800f2149c239c8727f31f7e70..1176c9c37f90c85cf2f3d2ef12cc40fee3d0d3c5 100644 --- a/module-sys/Service/Message.hpp +++ b/module-sys/Service/Message.hpp @@ -71,6 +71,22 @@ namespace sys ServicePowerMode powerMode; }; + class ServiceCloseReasonMessage : public Message + { + public: + explicit ServiceCloseReasonMessage(CloseReason closeReason); + + MessagePointer Execute(Service *service) final; + + CloseReason getCloseReason() const noexcept; + + private: + const CloseReason closeReason; + }; + + class ReadyToCloseMessage : public Message + {}; + class DataMessage : public Message { public: diff --git a/module-sys/Service/Service.cpp b/module-sys/Service/Service.cpp index f064b4b9f7e25baffb989867b66524d775b4f845..36c13bd80aa3b73366f549cad6d0a9a58dd552ee 100644 --- a/module-sys/Service/Service.cpp +++ b/module-sys/Service/Service.cpp @@ -19,6 +19,7 @@ #include // for uint32_t, uint64_t, UINT32_MAX #include // for std #include // for type_info +#include #if (DEBUG_SERVICE_MESSAGES > 0) #include @@ -184,6 +185,8 @@ namespace sys enableRunLoop = false; } + auto Service::ProcessCloseReason(CloseReason closeReason) -> void{}; + auto Service::TimerHandle(SystemMessage &message) -> ReturnCodes { auto timer_message = dynamic_cast(&message); @@ -209,6 +212,12 @@ namespace sys } } + void Service::sendCloseReadyMessage(Service *service) + { + auto msg = std::make_shared(); + service->bus.sendUnicast(std::move(msg), service::name::system_manager); + } + auto Proxy::handleMessage(Service *service, Message *message, ResponseMessage *response) -> MessagePointer { if (service->isReady) { @@ -243,4 +252,10 @@ namespace sys } return std::make_shared(ret); } + + auto Proxy::handleCloseReasonMessage(Service *service, ServiceCloseReasonMessage *message) -> void + { + service->ProcessCloseReason(message->getCloseReason()); + } + } // namespace sys diff --git a/module-sys/Service/Service.hpp b/module-sys/Service/Service.hpp index 2aa3acbb4d30e0ac45e93d5a0769743a9e02755c..6ff87f3e46ac20347ec27fdc5a55625c2ba6c30f 100644 --- a/module-sys/Service/Service.hpp +++ b/module-sys/Service/Service.hpp @@ -66,6 +66,8 @@ namespace sys */ virtual ReturnCodes DeinitHandler() = 0; + virtual auto ProcessCloseReason(CloseReason closeReason) -> void; + virtual ReturnCodes SwitchPowerModeHandler(const ServicePowerMode mode) = 0; /** @@ -92,6 +94,8 @@ namespace sys bool connect(Message *msg, MessageHandler handler); bool connect(Message &&msg, MessageHandler handler); + void sendCloseReadyMessage(Service *service); + protected: bool enableRunLoop; @@ -164,5 +168,6 @@ namespace sys static auto handleMessage(Service *service, Message *message, ResponseMessage *response = nullptr) -> MessagePointer; static auto handleSystemMessage(Service *service, SystemMessage *message) -> MessagePointer; + static auto handleCloseReasonMessage(Service *service, ServiceCloseReasonMessage *message) -> void; }; } // namespace sys diff --git a/module-sys/Service/Timer.cpp b/module-sys/Service/Timer.cpp index 9051076482f8e4cb90a8e33f27862cd4c056d639..f4e6021f9e0b9b6a0bf396fa9c4d18d091fa0e9f 100644 --- a/module-sys/Service/Timer.cpp +++ b/module-sys/Service/Timer.cpp @@ -111,4 +111,10 @@ namespace sys log_warn( "callback from %s non valid - %d, or not active - %d", name.c_str(), callback == nullptr, isActive != true); } + + bool Timer::isCurrentlyActive() const noexcept + { + return isActive; + } + } // namespace sys diff --git a/module-sys/Service/Timer.hpp b/module-sys/Service/Timer.hpp index 0430bcca66bfdc63d9efce66b8fa8c222c68f35e..76efa317161cf2d43bd5c8a21c9f7a6f4c48494b 100644 --- a/module-sys/Service/Timer.hpp +++ b/module-sys/Service/Timer.hpp @@ -61,6 +61,7 @@ namespace sys void reload(ms from_time = 0); void stop(); void setInterval(ms new_interval); + bool isCurrentlyActive() const noexcept; /// } protected: diff --git a/module-sys/SystemManager/SystemManager.cpp b/module-sys/SystemManager/SystemManager.cpp index bfa367969d61702032fad1d3deb296adde938a13..80b93a01b3d942568573d919920a6b271fc07b82 100644 --- a/module-sys/SystemManager/SystemManager.cpp +++ b/module-sys/SystemManager/SystemManager.cpp @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -39,6 +40,8 @@ namespace sys {bsp::KeyCodes::SSwitchUp, phone_modes::PhoneMode::Connected}, {bsp::KeyCodes::SSwitchMid, phone_modes::PhoneMode::DoNotDisturb}, {bsp::KeyCodes::SSwitchDown, phone_modes::PhoneMode::Offline}}; + + constexpr auto preShutdownRoutineTimeout = 1500; } // namespace using namespace cpp_freertos; @@ -93,7 +96,7 @@ namespace sys } } - DestroyService(service::name::evt_manager, this); + DestroySystemService(service::name::evt_manager, this); CloseService(); @@ -144,7 +147,7 @@ namespace sys } std::for_each(sortedServices.begin(), sortedServices.end(), [this](const auto &service) { const auto startTimeout = service.get().getStartTimeout().count(); - if (const auto success = RunService(service.get().create(), this, startTimeout); !success) { + if (const auto success = RunSystemService(service.get().create(), this, startTimeout); !success) { LOG_FATAL("Unable to start service: %s", service.get().getName().c_str()); } }); @@ -168,11 +171,6 @@ namespace sys cpuStatisticsTimer->start(); } - bool SystemManager::CloseSystem(Service *s) - { - s->bus.sendUnicast(std::make_shared(Code::CloseSystem), service::name::system_manager); - return true; - } bool SystemManager::Update(Service *s, const std::string &updateOSVer, std::string ¤tOSVer) { // set update OS version (and also current os version) in Settings @@ -230,10 +228,6 @@ namespace sys bool SystemManager::RunService(std::shared_ptr service, Service *caller, TickType_t timeout) { - CriticalSection::Enter(); - servicesList.push_back(service); - CriticalSection::Exit(); - service->StartService(); auto msg = std::make_shared(SystemMessageType::Start); @@ -246,9 +240,29 @@ namespace sys return false; } - bool SystemManager::DestroyService(const std::string &name, Service *caller, TickType_t timeout) + bool SystemManager::RunSystemService(std::shared_ptr service, Service *caller, TickType_t timeout) { + CriticalSection::Enter(); + servicesList.push_back(service); + CriticalSection::Exit(); + + return RunService(std::move(service), caller, timeout); + } + bool SystemManager::RunApplication(std::shared_ptr app, Service *caller, TickType_t timeout) + { + CriticalSection::Enter(); + applicationsList.push_back(app); + CriticalSection::Exit(); + + return RunService(std::move(app), caller, timeout); + } + + bool SystemManager::DestroyService(std::vector> &serviceContainer, + const std::string &name, + Service *caller, + TickType_t timeout) + { auto msg = std::make_shared(SystemMessageType::Exit); auto ret = caller->bus.sendUnicast(msg, name, timeout); auto resp = std::static_pointer_cast(ret.second); @@ -257,15 +271,15 @@ namespace sys cpp_freertos::LockGuard lck(destroyMutex); - auto serv = std::find_if(servicesList.begin(), servicesList.end(), [&](std::shared_ptr const &s) { - return s->GetName() == name; - }); - if (serv == servicesList.end()) { + auto serv = std::find_if(serviceContainer.begin(), + serviceContainer.end(), + [&name](std::shared_ptr const &s) { return s->GetName() == name; }); + if (serv == serviceContainer.end()) { LOG_ERROR("No such service to destroy in services list: %s", name.c_str()); return false; } - servicesList.erase(serv); + serviceContainer.erase(serv); return true; } @@ -275,6 +289,48 @@ namespace sys } } + bool SystemManager::DestroySystemService(const std::string &name, Service *caller, TickType_t timeout) + { + return DestroyService(servicesList, name, caller, timeout); + } + + bool SystemManager::DestroyApplication(const std::string &name, Service *caller, TickType_t timeout) + { + return DestroyService(applicationsList, name, caller, timeout); + } + + void SystemManager::preCloseRoutine(CloseReason closeReason) + { + for (const auto &service : servicesList) { + auto msg = std::make_shared(closeReason); + bus.sendUnicast(std::move(msg), service->GetName()); + readyForCloseRegister.push_back(service->GetName()); + } + + servicesPreShutdownRoutineTimeout = + std::make_unique("servicesPreShutdownRoutine", this, preShutdownRoutineTimeout); + servicesPreShutdownRoutineTimeout->connect([&](sys::Timer &) { CloseServices(); }); + servicesPreShutdownRoutineTimeout->start(); + } + + void SystemManager::readyToCloseHandler(Message *msg) + { + if (!readyForCloseRegister.empty() && servicesPreShutdownRoutineTimeout->isCurrentlyActive()) { + auto message = static_cast(msg); + LOG_INFO("ready to close %s", message->sender.c_str()); + readyForCloseRegister.erase( + std::remove(readyForCloseRegister.begin(), readyForCloseRegister.end(), message->sender), + readyForCloseRegister.end()); + + // All services responded + if (readyForCloseRegister.empty()) { + LOG_INFO("All services ready to close."); + servicesPreShutdownRoutineTimeout->stop(); + CloseServices(); + } + } + } + void SystemManager::kill(std::shared_ptr const &toKill) { auto ret = toKill->DeinitHandler(); @@ -294,7 +350,7 @@ namespace sys switch (data->type) { case Code::CloseSystem: - CloseSystemHandler(); + CloseSystemHandler(data->closeReason); break; case Code::Update: UpdateSystemHandler(); @@ -325,11 +381,8 @@ namespace sys }); connect(sevm::BatteryBrownoutMessage(), [&](Message *) { - LOG_INFO("Battery Brownout voltage level reached!"); - - auto msg = std::make_shared(); - bus.sendUnicast(msg, app::manager::ApplicationManager::ServiceName); - + LOG_INFO("Battery Brownout voltage level reached! Closing system..."); + CloseSystemHandler(CloseReason::SystemBrownout); return MessageNone{}; }); @@ -357,6 +410,16 @@ namespace sys return MessageNone{}; }); + connect(app::UserPowerDownRequest(), [&](Message *) { + CloseSystemHandler(CloseReason::RegularPowerDown); + return MessageNone{}; + }); + + connect(ReadyToCloseMessage(), [&](Message *msg) { + readyToCloseHandler(msg); + return MessageNone{}; + }); + connect(typeid(sys::CpuFrequencyMessage), [this](sys::Message *message) -> sys::MessagePointer { auto msg = static_cast(message); @@ -413,7 +476,7 @@ namespace sys return std::make_shared(); } - void SystemManager::CloseSystemHandler() + void SystemManager::CloseSystemHandler(CloseReason closeReason) { LOG_DEBUG("Invoking closing procedure..."); @@ -422,6 +485,15 @@ namespace sys std::reverse(servicesList.begin(), servicesList.end()); CriticalSection::Exit(); + preCloseRoutine(closeReason); + } + + void SystemManager::CloseServices() + { + for (const auto &element : readyForCloseRegister) { + LOG_INFO("Service: %s did not reported before timeout", element.c_str()); + } + for (bool retry{};; retry = false) { for (auto &service : servicesList) { if (service->GetName() == service::name::evt_manager) { @@ -429,7 +501,7 @@ namespace sys continue; } if (service->parent == "") { - const auto ret = DestroyService(service->GetName(), this); + const auto ret = DestroySystemService(service->GetName(), this); if (!ret) { // no response to exit message, LOG_FATAL("%s", (service->GetName() + " failed to response to exit message").c_str()); @@ -486,7 +558,7 @@ namespace sys continue; } if (service->parent.empty()) { - const auto ret = DestroyService(service->GetName(), this); + const auto ret = DestroySystemService(service->GetName(), this); if (!ret) { // no response to exit message, LOG_FATAL("%s failed to response to exit message", service->GetName().c_str()); @@ -504,7 +576,7 @@ namespace sys void SystemManager::RebootHandler() { - CloseSystemHandler(); + CloseSystemHandler(CloseReason::Reboot); set(State::Reboot); } @@ -544,6 +616,7 @@ namespace sys } std::vector> SystemManager::servicesList; + std::vector> SystemManager::applicationsList; cpp_freertos::MutexStandard SystemManager::destroyMutex; std::unique_ptr SystemManager::powerManager; std::unique_ptr SystemManager::cpuStatistics; diff --git a/module-sys/SystemManager/SystemManager.hpp b/module-sys/SystemManager/SystemManager.hpp index e78d41ff8d2ae6059ab92c1d8563a7bae6dbb709..96e2e4bd86d1ade6f059fa0492f9181cf8ce3265 100644 --- a/module-sys/SystemManager/SystemManager.hpp +++ b/module-sys/SystemManager/SystemManager.hpp @@ -50,10 +50,12 @@ namespace sys class SystemManagerCmd : public DataMessage { public: - SystemManagerCmd(Code type = Code::None) : DataMessage(BusChannel::SystemManagerRequests), type(type) + explicit SystemManagerCmd(Code type = Code::None, CloseReason closeReason = CloseReason::RegularPowerDown) + : DataMessage(BusChannel::SystemManagerRequests), type(type), closeReason(closeReason) {} Code type; + CloseReason closeReason; }; class SystemManager : public Service @@ -79,9 +81,6 @@ namespace sys void StartSystem(InitFunction sysInit, InitFunction appSpaceInit); - // Invoke system close procedure - static bool CloseSystem(Service *s); - static bool Update(Service *s, const std::string &updateOSVer, std::string ¤tOSVer); static bool Reboot(Service *s); @@ -93,11 +92,15 @@ namespace sys static bool ResumeService(const std::string &name, Service *caller); /// Runs a service - static bool RunService(std::shared_ptr service, Service *caller, TickType_t timeout = 5000); + static bool RunSystemService(std::shared_ptr service, Service *caller, TickType_t timeout = 5000); + /// Runs an application + static bool RunApplication(std::shared_ptr service, Service *caller, TickType_t timeout = 5000); /// Destroy existing service /// @note there is no fallback - static bool DestroyService(const std::string &name, Service *caller, TickType_t timeout = 5000); + static bool DestroySystemService(const std::string &name, Service *caller, TickType_t timeout = 5000); + /// Destroy existing application + static bool DestroyApplication(const std::string &name, Service *caller, TickType_t timeout = 5000); /// Translates a slider state into a phone mode. /// \param key Slider button state @@ -133,12 +136,24 @@ namespace sys void StartSystemServices(); + static bool RunService(std::shared_ptr service, Service *caller, TickType_t timeout = 5000); + static bool DestroyService(std::vector> &serviceContainer, + const std::string &name, + Service *caller, + TickType_t timeout = 5000); + /// Sysmgr stores list of all active services but some of them are under control of parent services. /// Parent services ought to manage lifetime of child services hence we are sending DestroyRequests only to /// parents. /// It closes all workers except EventManager -as it needs information from Eventmanager that it's safe to /// shutdown - void CloseSystemHandler(); + void CloseSystemHandler(CloseReason closeReason = CloseReason::RegularPowerDown); + + void CloseServices(); + + void preCloseRoutine(CloseReason closeReason); + + void readyToCloseHandler(Message *msg); void UpdateSystemHandler(); @@ -162,11 +177,14 @@ namespace sys std::vector> systemServiceCreators; std::unique_ptr cpuStatisticsTimer; + std::unique_ptr servicesPreShutdownRoutineTimeout; std::unique_ptr phoneModeSubject; InitFunction userInit; InitFunction systemInit; + std::vector readyForCloseRegister; static std::vector> servicesList; + static std::vector> applicationsList; static cpp_freertos::MutexStandard destroyMutex; static std::unique_ptr powerManager; static std::unique_ptr cpuStatistics; diff --git a/module-sys/SystemManager/doc/SystemCloseSequence.md b/module-sys/SystemManager/doc/SystemCloseSequence.md new file mode 100644 index 0000000000000000000000000000000000000000..f5c8ab53cc8d1a812e1ed7df663843b906e32879 --- /dev/null +++ b/module-sys/SystemManager/doc/SystemCloseSequence.md @@ -0,0 +1,10 @@ +# Sequence flow when closing the system + +Regular power down via menu + +![](./system_close_procedure_user.svg) + + +Close at Brownout event + +![](./system_close_procedure_brownout.svg) \ No newline at end of file diff --git a/module-sys/SystemManager/doc/system_close_procedure_brownout.puml b/module-sys/SystemManager/doc/system_close_procedure_brownout.puml new file mode 100644 index 0000000000000000000000000000000000000000..020d1f673439106194a8ddabb8a354577740bd9d --- /dev/null +++ b/module-sys/SystemManager/doc/system_close_procedure_brownout.puml @@ -0,0 +1,27 @@ +@startuml + +participant "System Manager" as sysmgr +participant "All services" as srv +participant "Application Manager" as appmgr +participant "Service GUI" as gui +participant "service EINK" as eink + +-> sysmgr : battery brownout +sysmgr -> srv : preCloseRoutine + +srv -> appmgr : processCloseReason +appmgr -> appmgr : switchWindowAtClose(Dead Battery Window) +eink -> gui : last sreen show +gui -> srv : ready to close + +srv -> sysmgr : readyToClose +alt timeout +sysmgr -> sysmgr : closeServices +end +sysmgr -> srv : SystemMessageType::Exit +srv -> sysmgr : MsgHandled +alt timeout +sysmgr -> sysmgr : kill service +end + +@enduml diff --git a/module-sys/SystemManager/doc/system_close_procedure_brownout.svg b/module-sys/SystemManager/doc/system_close_procedure_brownout.svg new file mode 100644 index 0000000000000000000000000000000000000000..45df52041ca5ebf5f48163c176222c6ba5ad7448 --- /dev/null +++ b/module-sys/SystemManager/doc/system_close_procedure_brownout.svg @@ -0,0 +1,37 @@ +System ManagerSystem ManagerAll servicesAll servicesApplication ManagerApplication ManagerService GUIService GUIservice EINKservice EINKbattery brownoutpreCloseRoutineprocessCloseReasonswitchWindowAtClose(Dead Battery Window)last sreen showready to closereadyToClosealt[timeout]closeServicesSystemMessageType::ExitMsgHandledalt[timeout]kill service \ No newline at end of file diff --git a/module-sys/SystemManager/doc/system_close_procedure_user.puml b/module-sys/SystemManager/doc/system_close_procedure_user.puml new file mode 100644 index 0000000000000000000000000000000000000000..ca457c1aa8ad69aeacf75b742b6dabf89f836f7a --- /dev/null +++ b/module-sys/SystemManager/doc/system_close_procedure_user.puml @@ -0,0 +1,32 @@ +@startuml + +actor User +participant "PowerOffWindow" as poff +participant "Application" as app +participant "System Manager" as sysmgr +participant "All services" as srv +participant "Application Manager" as appmgr +participant "Service GUI" as gui +participant "service EINK" as eink + +User -> poff : confirm close +poff -> app : GUI off switch +app -> sysmgr : UserPowerDownRequest +sysmgr -> srv : preCloseRoutine + +srv -> appmgr : processCloseReason +appmgr -> appmgr : switchWindowAtClose(logo) +eink -> gui : last sreen show +gui -> srv : ready to close + +srv -> sysmgr : readyToClose +alt timeout +sysmgr -> sysmgr : closeServices +end +sysmgr -> srv : SystemMessageType::Exit +srv -> sysmgr : MsgHandled +alt timeout +sysmgr -> sysmgr : kill service +end + +@enduml diff --git a/module-sys/SystemManager/doc/system_close_procedure_user.svg b/module-sys/SystemManager/doc/system_close_procedure_user.svg new file mode 100644 index 0000000000000000000000000000000000000000..2fe79706523b61a9d716476de975bd6bd133eb46 --- /dev/null +++ b/module-sys/SystemManager/doc/system_close_procedure_user.svg @@ -0,0 +1,42 @@ +UserUserPowerOffWindowPowerOffWindowApplicationApplicationSystem ManagerSystem ManagerAll servicesAll servicesApplication ManagerApplication ManagerService GUIService GUIservice EINKservice EINKconfirm closeGUI off switchUserPowerDownRequestpreCloseRoutineprocessCloseReasonswitchWindowAtClose(logo)last sreen showready to closereadyToClosealt[timeout]closeServicesSystemMessageType::ExitMsgHandledalt[timeout]kill service \ No newline at end of file diff --git a/module-sys/SystemManager/messages/SystemManagerMessage.hpp b/module-sys/SystemManager/messages/SystemManagerMessage.hpp index 7386e5788a8c1856edeb8a6a728e314abaa9f117..16a866ad8a79b6cf77de88c494edf8eeb5df63f0 100644 --- a/module-sys/SystemManager/messages/SystemManagerMessage.hpp +++ b/module-sys/SystemManager/messages/SystemManagerMessage.hpp @@ -37,14 +37,4 @@ namespace sys bool isActive; }; - class SystemBrownoutMesssage : public sys::Message, public app::manager::actions::ConvertibleToAction - { - public: - [[nodiscard]] auto toAction() const -> std::unique_ptr - { - return std::make_unique( - service::name::system_manager, app::manager::actions::SystemBrownout, nullptr); - } - }; - } // namespace sys diff --git a/source/main.cpp b/source/main.cpp index a72eaedbe1f211a39f23b25bfd1214d367c49ca1..390c85489e5983961f6c785a52cbdba466325c9d 100644 --- a/source/main.cpp +++ b/source/main.cpp @@ -174,7 +174,7 @@ int main() applications.push_back(app::CreateLauncher(app::name_onboarding)); #endif // start application manager - return sysmgr->RunService( + return sysmgr->RunSystemService( std::make_shared( app::manager::ApplicationManager::ServiceName, std::move(applications), app::name_desktop), sysmgr.get());