From e71a044bd3f7df980802cdcdb29ad48c9cd427df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Przemys=C5=82aw=20Brudny?= <60609703+PrzeBrudny@users.noreply.github.com> Date: Fri, 14 May 2021 08:55:01 +0200 Subject: [PATCH] [EGD-6019] Revert of two commits This reverts commit b6416b15dac3a638d803681fbad8746b1808b6aa. This reverts commit e2f3882d8a0194ae6f74bfc5ab6104c368174517. --- enabled_unittests | 10 - module-apps/Application.cpp | 5 +- .../ApplicationDesktop.cpp | 2 + .../ApplicationSettings.cpp | 2 +- .../models/FactoryData.cpp | 14 +- .../models/FactoryData.hpp | 4 +- .../model/ApplicationManager.cpp | 5 +- .../service-audio/ServiceAudio.cpp | 4 +- .../service-bluetooth/ServiceBluetooth.cpp | 9 +- .../service-bluetooth/SettingsHolder.cpp | 5 - .../service-bluetooth/SettingsHolder.hpp | 1 - .../service-cellular/ServiceCellular.cpp | 28 +- module-services/service-db/CMakeLists.txt | 1 - module-services/service-db/EntryPath.cpp | 20 +- .../service-db/agents/settings/Settings.cpp | 263 ++++++++++++++---- .../agents/settings/SettingsAgent.cpp | 255 +++++++++++++++++ .../agents/settings/SettingsAgent.hpp | 30 ++ .../agents/settings/SettingsCache.cpp | 54 +--- .../agents/settings/SettingsProxy.cpp | 81 ------ .../service-db/service-db/EntryPath.hpp | 30 -- .../service-db/service-db/Settings.hpp | 57 +++- .../service-db/service-db/SettingsCache.hpp | 8 +- .../service-db/SettingsMessages.hpp | 232 ++++++++++++++- .../service-db/service-db/SettingsProxy.hpp | 30 -- .../service-db/test/CMakeLists.txt | 1 - .../test-service-db-settings-messages.cpp | 48 +++- .../test-settings-Settings/CMakeLists.txt | 17 -- .../test/test-settings-Settings/main.cpp | 5 - .../test-settings-Interface.cpp | 72 ----- .../test-settings-Settings.cpp | 91 ------ .../test/test-settings/CMakeLists.txt | 2 + .../test-service-db-settings-api.cpp | 127 ++++++--- .../test-service-db-settings-testapps.hpp | 89 +++--- .../test-service-db-settings-testservices.hpp | 119 +++++++- .../service-desktop/ServiceDesktop.cpp | 7 +- .../developerMode/DeveloperModeHelper.cpp | 1 - .../service-evtmgr/EventManager.cpp | 16 +- .../service-evtmgr/EventManager.hpp | 2 +- module-sys/Service/Common.hpp | 1 + module-sys/Service/Service.hpp | 14 +- module-sys/Service/ServiceForward.hpp | 20 -- module-sys/Service/ServiceProxy.hpp | 46 --- module-utils/Split.hpp | 51 ---- module-utils/Utils.hpp | 43 ++- test/mock-freertos-tls.cpp | 6 +- 45 files changed, 1162 insertions(+), 766 deletions(-) delete mode 100644 module-services/service-db/agents/settings/SettingsProxy.cpp delete mode 100644 module-services/service-db/service-db/EntryPath.hpp delete mode 100644 module-services/service-db/service-db/SettingsProxy.hpp delete mode 100644 module-services/service-db/test/test-settings-Settings/CMakeLists.txt delete mode 100644 module-services/service-db/test/test-settings-Settings/main.cpp delete mode 100644 module-services/service-db/test/test-settings-Settings/test-settings-Interface.cpp delete mode 100644 module-services/service-db/test/test-settings-Settings/test-settings-Settings.cpp delete mode 100644 module-sys/Service/ServiceForward.hpp delete mode 100644 module-sys/Service/ServiceProxy.hpp delete mode 100644 module-utils/Split.hpp diff --git a/enabled_unittests b/enabled_unittests index ffd8eb7e8..b04e527a1 100644 --- a/enabled_unittests +++ b/enabled_unittests @@ -479,15 +479,5 @@ TESTS_LIST["catch2-unittest_CellularResult"]=" CellularResult; " #--------- -TESTS_LIST["catch2-settings-Settings"]=" - Settings - not initialized; - Settings - initialized; - Interface - not initialized; - Interface - initialized; - Interface - expired; - Interface - copied; -" -#--------- - diff --git a/module-apps/Application.cpp b/module-apps/Application.cpp index cd8f526d1..2bbb77a23 100644 --- a/module-apps/Application.cpp +++ b/module-apps/Application.cpp @@ -102,7 +102,7 @@ namespace app default_window(gui::name::window::main_window), windowsStack(this), keyTranslator{std::make_unique()}, startInBackground{startInBackground}, callbackStorage{std::make_unique()}, topBarManager{std::make_unique()}, - settings(std::make_unique()), phoneMode{mode}, phoneLockSubject(this) + settings(std::make_unique(this)), phoneMode{mode}, phoneLockSubject(this) { topBarManager->enableIndicators({gui::top_bar::Indicator::Time}); using TimeMode = gui::top_bar::TimeConfiguration::TimeMode; @@ -154,6 +154,7 @@ namespace app Application::~Application() noexcept { windowsStack.windows.clear(); + settings->unregisterValueChange(); } Application::State Application::getState() @@ -620,7 +621,6 @@ namespace app { setState(State::INITIALIZING); - settings->init(service::ServiceProxy(shared_from_this())); app::manager::Controller::applicationInitialised(this, StartupStatus::Success, startInBackground); if (startInBackground) { @@ -638,7 +638,6 @@ namespace app sys::ReturnCodes Application::DeinitHandler() { - settings->deinit(); LOG_INFO("Closing an application: %s", GetName().c_str()); for (const auto &[windowName, window] : windowsStack) { diff --git a/module-apps/application-desktop/ApplicationDesktop.cpp b/module-apps/application-desktop/ApplicationDesktop.cpp index 44ceae00f..bd24b1b35 100644 --- a/module-apps/application-desktop/ApplicationDesktop.cpp +++ b/module-apps/application-desktop/ApplicationDesktop.cpp @@ -383,6 +383,8 @@ namespace app sys::ReturnCodes ApplicationDesktop::DeinitHandler() { + LOG_INFO("DeinitHandler"); + settings->unregisterValueChange(); return sys::ReturnCodes::Success; } diff --git a/module-apps/application-settings-new/ApplicationSettings.cpp b/module-apps/application-settings-new/ApplicationSettings.cpp index 5aa82d09e..8300e1c0c 100644 --- a/module-apps/application-settings-new/ApplicationSettings.cpp +++ b/module-apps/application-settings-new/ApplicationSettings.cpp @@ -460,7 +460,7 @@ namespace app return std::make_unique(app); }); windowsFactory.attach(gui::window::name::technical_information, [&](Application *app, const std::string &name) { - auto factoryData = std::make_unique(*settings); + auto factoryData = std::make_unique(std::make_unique<::settings::Settings>(this)); auto presenter = std::make_unique(std::move(factoryData)); return std::make_unique(app, std::move(presenter)); }); diff --git a/module-apps/application-settings-new/models/FactoryData.cpp b/module-apps/application-settings-new/models/FactoryData.cpp index 628e80b88..105b6efd4 100644 --- a/module-apps/application-settings-new/models/FactoryData.cpp +++ b/module-apps/application-settings-new/models/FactoryData.cpp @@ -5,28 +5,28 @@ #include #include -FactoryData::FactoryData(settings::Settings &settings) : settings(settings) +FactoryData::FactoryData(std::unique_ptr settingsProvider) : settings(std::move(settingsProvider)) {} auto FactoryData::getModel() -> std::string { - return settings.getValue(settings::factory::entry_key + std::string("/model"), settings::SettingsScope::Global); + return settings->getValue(settings::factory::entry_key + std::string("/model"), settings::SettingsScope::Global); } auto FactoryData::getCase() -> std::string { - return settings.getValue(settings::factory::entry_key + std::string("/case"), ::settings::SettingsScope::Global); + return settings->getValue(settings::factory::entry_key + std::string("/case"), ::settings::SettingsScope::Global); } auto FactoryData::getSerial() -> std::string { - return settings.getValue(settings::factory::entry_key + std::string("/serial"), settings::SettingsScope::Global); + return settings->getValue(settings::factory::entry_key + std::string("/serial"), settings::SettingsScope::Global); } auto FactoryData::getBatteryRev() -> std::string { - return settings.getValue(settings::factory::entry_key + std::string("/battery_revision"), - settings::SettingsScope::Global); + return settings->getValue(settings::factory::entry_key + std::string("/battery_revision"), + settings::SettingsScope::Global); } auto FactoryData::getPcb(std::string type) -> std::string { std::string full_pcb = "/pcb_" + type + "_version"; - return settings.getValue(settings::factory::entry_key + full_pcb, settings::SettingsScope::Global); + return settings->getValue(settings::factory::entry_key + full_pcb, settings::SettingsScope::Global); } diff --git a/module-apps/application-settings-new/models/FactoryData.hpp b/module-apps/application-settings-new/models/FactoryData.hpp index 87b6a4140..f21f0393a 100644 --- a/module-apps/application-settings-new/models/FactoryData.hpp +++ b/module-apps/application-settings-new/models/FactoryData.hpp @@ -20,7 +20,7 @@ class AbstractFactoryData class FactoryData : public AbstractFactoryData { public: - explicit FactoryData(settings::Settings &settings); + explicit FactoryData(std::unique_ptr settings); auto getModel() -> std::string override; auto getCase() -> std::string override; @@ -29,5 +29,5 @@ class FactoryData : public AbstractFactoryData auto getPcb(std::string type) -> std::string override; private: - settings::Settings &settings; + std::unique_ptr settings; }; diff --git a/module-services/service-appmgr/model/ApplicationManager.cpp b/module-services/service-appmgr/model/ApplicationManager.cpp index 765095537..6499ec60c 100644 --- a/module-services/service-appmgr/model/ApplicationManager.cpp +++ b/module-services/service-appmgr/model/ApplicationManager.cpp @@ -134,7 +134,7 @@ namespace app::manager : Service{serviceName, {}, ApplicationManagerStackDepth}, ApplicationManagerBase(std::move(launchers)), rootApplicationName{_rootApplicationName}, actionsRegistry{[this](ActionEntry &action) { return handleAction(action); }}, notificationProvider(this), - autoLockEnabled(false), settings(std::make_unique()), + autoLockEnabled(false), settings(std::make_unique(this)), phoneModeObserver(std::make_unique()), phoneLockHandler(locks::PhoneLockHandler(this)) { @@ -148,7 +148,6 @@ namespace app::manager sys::ReturnCodes ApplicationManager::InitHandler() { - settings->init(service::ServiceProxy(shared_from_this())); utils::setDisplayLanguage( settings->getValue(settings::SystemProperties::displayLanguage, settings::SettingsScope::Global)); @@ -260,7 +259,7 @@ namespace app::manager sys::ReturnCodes ApplicationManager::DeinitHandler() { - settings->deinit(); + settings->unregisterValueChange(); closeApplications(); return sys::ReturnCodes::Success; } diff --git a/module-services/service-audio/ServiceAudio.cpp b/module-services/service-audio/ServiceAudio.cpp index b496a1144..27c9f0226 100644 --- a/module-services/service-audio/ServiceAudio.cpp +++ b/module-services/service-audio/ServiceAudio.cpp @@ -94,7 +94,7 @@ static constexpr std::initializer_listAudioServicesCallback(params...); }), - settingsProvider(std::make_unique()) + settingsProvider(std::make_unique(this)) { LOG_INFO("[ServiceAudio] Initializing"); bus.channels.push_back(sys::BusChannel::ServiceAudioNotifications); @@ -110,7 +110,6 @@ ServiceAudio::~ServiceAudio() sys::ReturnCodes ServiceAudio::InitHandler() { - settingsProvider->init(service::ServiceProxy(shared_from_this())); std::transform(std::begin(cacheInitializer), std::end(cacheInitializer), std::inserter(settingsCache, std::end(settingsCache)), @@ -126,7 +125,6 @@ sys::ReturnCodes ServiceAudio::InitHandler() sys::ReturnCodes ServiceAudio::DeinitHandler() { - settingsProvider->deinit(); return sys::ReturnCodes::Success; } diff --git a/module-services/service-bluetooth/ServiceBluetooth.cpp b/module-services/service-bluetooth/ServiceBluetooth.cpp index 03b20c718..840974861 100644 --- a/module-services/service-bluetooth/ServiceBluetooth.cpp +++ b/module-services/service-bluetooth/ServiceBluetooth.cpp @@ -45,6 +45,9 @@ namespace ServiceBluetooth::ServiceBluetooth() : sys::Service(service::name::bluetooth, "", BluetoothServiceStackDepth) { + auto settings = std::make_unique(this); + settingsHolder = std::make_shared(std::move(settings)); + bluetooth::KeyStorage::settings = settingsHolder; LOG_INFO("[ServiceBluetooth] Initializing"); } @@ -57,11 +60,6 @@ ServiceBluetooth::~ServiceBluetooth() // this means it is an init point of bluetooth feature handling sys::ReturnCodes ServiceBluetooth::InitHandler() { - auto settings = std::make_unique(); - settings->init(service::ServiceProxy(shared_from_this())); - settingsHolder = std::make_shared(std::move(settings)); - bluetooth::KeyStorage::settings = settingsHolder; - worker = std::make_unique(this); worker->run(); @@ -107,7 +105,6 @@ sys::ReturnCodes ServiceBluetooth::InitHandler() sys::ReturnCodes ServiceBluetooth::DeinitHandler() { - settingsHolder->deinit(); worker->deinit(); return sys::ReturnCodes::Success; } diff --git a/module-services/service-bluetooth/service-bluetooth/SettingsHolder.cpp b/module-services/service-bluetooth/service-bluetooth/SettingsHolder.cpp index 5b446d776..61b2b77e6 100644 --- a/module-services/service-bluetooth/service-bluetooth/SettingsHolder.cpp +++ b/module-services/service-bluetooth/service-bluetooth/SettingsHolder.cpp @@ -53,9 +53,4 @@ namespace bluetooth } }); } - - void SettingsHolder::deinit() - { - settingsProvider->deinit(); - } } // namespace Bluetooth diff --git a/module-services/service-bluetooth/service-bluetooth/SettingsHolder.hpp b/module-services/service-bluetooth/service-bluetooth/SettingsHolder.hpp index 7e1638272..f0c9836e1 100644 --- a/module-services/service-bluetooth/service-bluetooth/SettingsHolder.hpp +++ b/module-services/service-bluetooth/service-bluetooth/SettingsHolder.hpp @@ -84,7 +84,6 @@ namespace bluetooth void setValue(const Settings &newSetting, const SettingEntry &value); std::function onStateChange; std::function onLinkKeyAdded; - void deinit(); private: static std::map settingString; diff --git a/module-services/service-cellular/ServiceCellular.cpp b/module-services/service-cellular/ServiceCellular.cpp index 4a1bc705a..96456e513 100644 --- a/module-services/service-cellular/ServiceCellular.cpp +++ b/module-services/service-cellular/ServiceCellular.cpp @@ -180,6 +180,15 @@ ServiceCellular::ServiceCellular() bus.channels.push_back(sys::BusChannel::ServiceEvtmgrNotifications); bus.channels.push_back(sys::BusChannel::PhoneModeChanges); + settings = std::make_unique(this); + + connectionManager = std::make_unique( + utils::getNumericValue( + settings->getValue(settings::Cellular::offlineMode, settings::SettingsScope::Global)), + static_cast(utils::getNumericValue(settings->getValue( + settings->getValue(settings::Offline::connectionFrequency, settings::SettingsScope::Global)))), + std::make_shared(*this)); + callStateTimer = sys::TimerFactory::createPeriodicTimer( this, "call_state", std::chrono::milliseconds{1000}, [this](sys::Timer &) { CallStateTimerHandler(); }); stateTimer = sys::TimerFactory::createPeriodicTimer( @@ -192,10 +201,7 @@ ServiceCellular::ServiceCellular() sys::TimerFactory::createPeriodicTimer(this, "connection", std::chrono::seconds{60}, [this](sys::Timer &) { utility::conditionally_invoke( [this]() { return phoneModeObserver->isInMode(sys::phone_modes::PhoneMode::Offline); }, - [this]() { - if (connectionManager != nullptr) - connectionManager->onTimerTick(); - }); + [this]() { connectionManager->onTimerTick(); }); }); ongoingCall.setStartCallAction([=](const CalllogRecord &rec) { @@ -242,6 +248,8 @@ ServiceCellular::ServiceCellular() ServiceCellular::~ServiceCellular() { LOG_INFO("[ServiceCellular] Cleaning resources"); + settings->unregisterValueChange(settings::Cellular::volte_on, ::settings::SettingsScope::Global); + settings->unregisterValueChange(settings::Cellular::apn_list, ::settings::SettingsScope::Global); } // this static function will be replaced by Settings API @@ -276,16 +284,6 @@ sys::ReturnCodes ServiceCellular::InitHandler() { board = EventManagerServiceAPI::GetBoard(this); - settings = std::make_unique(); - settings->init(service::ServiceProxy(shared_from_this())); - - connectionManager = std::make_unique( - utils::getNumericValue( - settings->getValue(settings::Cellular::offlineMode, settings::SettingsScope::Global)), - static_cast(utils::getNumericValue(settings->getValue( - settings->getValue(settings::Offline::connectionFrequency, settings::SettingsScope::Global)))), - std::make_shared(*this)); - state.set(this, State::ST::WaitForStartPermission); settings->registerValueChange( settings::Cellular::volte_on, @@ -309,7 +307,7 @@ sys::ReturnCodes ServiceCellular::InitHandler() sys::ReturnCodes ServiceCellular::DeinitHandler() { - settings->deinit(); + return sys::ReturnCodes::Success; } diff --git a/module-services/service-db/CMakeLists.txt b/module-services/service-db/CMakeLists.txt index b908c1ddc..2b7f1e059 100644 --- a/module-services/service-db/CMakeLists.txt +++ b/module-services/service-db/CMakeLists.txt @@ -15,7 +15,6 @@ set(SOURCES messages/QueryMessage.cpp agents/settings/SettingsAgent.cpp agents/settings/Settings.cpp - agents/settings/SettingsProxy.cpp agents/settings/SettingsCache.cpp agents/settings/FactorySettings.cpp agents/file_indexer/FileIndexerAgent.cpp diff --git a/module-services/service-db/EntryPath.cpp b/module-services/service-db/EntryPath.cpp index 3694a9b48..c475b9b87 100644 --- a/module-services/service-db/EntryPath.cpp +++ b/module-services/service-db/EntryPath.cpp @@ -1,28 +1,10 @@ // Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved. // For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md -#include "service-db/EntryPath.hpp" -#include +#include "service-db/SettingsMessages.hpp" namespace settings { - - void EntryPath::parse(const std::string &dbPath) - { - auto parts = utils::split(dbPath, "\\", false); - if (1 == parts.size()) { - variable = dbPath; - scope = SettingsScope::Global; - } - else { - mode = parts[0]; - service = parts[1]; - profile = parts[2]; - variable = parts[3]; - scope = SettingsScope::AppLocal; - } - } - namespace { bool isLessAppLocal(const EntryPath &lhs, const EntryPath &rhs) noexcept diff --git a/module-services/service-db/agents/settings/Settings.cpp b/module-services/service-db/agents/settings/Settings.cpp index 21a3310c5..8cfbac52f 100644 --- a/module-services/service-db/agents/settings/Settings.cpp +++ b/module-services/service-db/agents/settings/Settings.cpp @@ -2,15 +2,18 @@ // For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md #include +#include #include -#include -#include +#include +#include +#include +#include + #include #include #if defined(DEBUG_SETTINGS_DB) and DEBUG_SETTINGS_DB == 1 -#include #define log_debug(...) LOG_DEBUG(__VA_ARGS__); #else #define log_debug(...) @@ -18,101 +21,259 @@ namespace settings { - Settings::~Settings() + Settings::Settings(sys::Service *app, const std::string &dbAgentName, SettingsCache *cache) + : dbAgentName(dbAgentName), cache(cache) { - deinit(); + this->app = + std::shared_ptr(app, [](sys::Service *service) {}); /// with deleter that doesn't delete. + this->app->bus.channels.push_back(sys::BusChannel::ServiceDBNotifications); + if (nullptr == cache) { + this->cache = SettingsCache::getInstance(); + } + registerHandlers(); } - void Settings::init(const service::ServiceProxy &interface) + void Settings::sendMsg(std::shared_ptr &&msg) { - this->interface = SettingsProxy(interface); - this->interface.init([&](const EntryPath &p, const std::string &v) { this->handleVariableChanged(p, v); }); - if (not interface.isValid()) { - throw std::invalid_argument("need the interface!"); - } + app->bus.sendUnicast(std::move(msg), dbAgentName); } - void Settings::deinit() + void Settings::registerHandlers() { - if (interface.isValid()) { - interface.deinit(); - for (const auto &callbacks : cbValues) { - log_debug("[Settings::unregisterValueChange] %s", callbacks.first.to_string().c_str()); - interface.unregisterValueChange(callbacks.first); - } - } - cbValues.clear(); + using std::placeholders::_1; + using std::placeholders::_2; + log_debug("Settings::registerHandlers for %s", app->GetName().c_str()); + app->connect(settings::Messages::VariableChanged(), std::bind(&Settings::handleVariableChanged, this, _1)); + app->connect(settings::Messages::CurrentProfileChanged(), + std::bind(&Settings::handleCurrentProfileChanged, this, _1)); + app->connect(settings::Messages::CurrentModeChanged(), + std::bind(&Settings::handleCurrentModeChanged, this, _1)); + app->connect(settings::Messages::ProfileListResponse(), + std::bind(&Settings::handleProfileListResponse, this, _1)); + app->connect(settings::Messages::ModeListResponse(), std::bind(&Settings::handleModeListResponse, this, _1)); } - - void Settings::handleVariableChanged(const EntryPath &path, const std::string &value) + auto Settings::handleVariableChanged(sys::Message *req) -> sys::MessagePointer { - log_debug("handleVariableChanged: (k=v): (%s=%s)", path.to_string().c_str(), value.c_str()); - if (auto callbacks = cbValues.find(path); std::end(cbValues) != callbacks) { - auto &[cb, cbWithName] = callbacks->second; - if (nullptr != cb) { - cb(value); - } - if (nullptr != cbWithName) { - cbWithName(path.variable, value); + log_debug("handleVariableChanged"); + if (auto msg = dynamic_cast(req)) { + auto key = msg->getPath(); + auto val = msg->getValue(); + log_debug("handleVariableChanged: (k=v): (%s=%s)", key.to_string().c_str(), val.value_or("").c_str()); + ValueCb::iterator it_cb = cbValues.find(key); + if (cbValues.end() != it_cb) { + auto [cb, cbWithName] = it_cb->second; + if (nullptr != cb && nullptr != cbWithName) { + // in case of two callbacks there is a need to duplicate the value + auto value = val.value_or(""); + cb(std::string{value}); + cbWithName(key.variable, value); + } + else if (nullptr != cb) { + cb(val.value_or("")); + } + else { + cbWithName(key.variable, val.value_or("")); + } } } + return std::make_shared(); + } + auto Settings::handleCurrentProfileChanged(sys::Message *req) -> sys::MessagePointer + { + log_debug("handleCurrentProfileChanged"); + if (auto msg = dynamic_cast(req)) { + auto profile = msg->getProfileName(); + log_debug("handleCurrentProfileChanged: %s", profile.c_str()); + cbProfile(profile); + } + return std::make_shared(); + } + auto Settings::handleCurrentModeChanged(sys::Message *req) -> sys::MessagePointer + { + log_debug("handleCurrentModeChanged"); + if (auto msg = dynamic_cast(req)) { + auto mode = msg->getProfileName(); + log_debug("handleCurrentModeChanged: %s", mode.c_str()); + cbMode(mode); + } + return std::make_shared(); + } + auto Settings::handleProfileListResponse(sys::Message *req) -> sys::MessagePointer + { + log_debug("handleProfileListResponse"); + if (auto msg = dynamic_cast(req)) { + auto profiles = msg->getValue(); + log_debug("handleProfileListResponse: %zu elements", profiles.size()); + cbAllProfiles(profiles); + } + return std::make_shared(); + } + auto Settings::handleModeListResponse(sys::Message *req) -> sys::MessagePointer + { + log_debug("handleModeListResponse"); + if (auto msg = dynamic_cast(req)) { + auto modes = msg->getValue(); + log_debug("handleModeListResponse: %zu elements", modes.size()); + cbAllModes(modes); + } + return std::make_shared(); } void Settings::registerValueChange(const std::string &variableName, ValueChangedCallback cb, SettingsScope scope) { - auto path = EntryPath{.service = interface.ownerName(), .variable = variableName, .scope = scope}; + EntryPath path; + path.variable = variableName; + path.service = app->GetName(); + path.scope = scope; - if (auto callbacks = cbValues.find(path); - std::end(cbValues) != callbacks && nullptr != callbacks->second.first) { - log_debug("Callback function on value change (%s) already exists, rewriting", path.to_string().c_str()); + auto it_cb = cbValues.find(path); + if (cbValues.end() != it_cb && nullptr != it_cb->second.first) { + LOG_INFO("Callback function on value change (%s) already exists, rewriting", path.to_string().c_str()); } cbValues[path].first = std::move(cb); - interface.registerValueChange(std::move(path)); + + auto msg = std::make_shared(path); + sendMsg(std::move(msg)); } void Settings::registerValueChange(const std::string &variableName, ValueChangedCallbackWithName cb, SettingsScope scope) { - auto path = EntryPath{.service = interface.ownerName(), .variable = variableName, .scope = scope}; + EntryPath path; + path.variable = variableName; + path.service = app->GetName(); + path.scope = scope; - if (auto callbacks = cbValues.find(path); cbValues.end() != callbacks && nullptr != callbacks->second.second) { - log_debug("Callback function on value change (%s) already exists, rewriting", path.to_string().c_str()); + auto it_cb = cbValues.find(path); + if (cbValues.end() != it_cb && nullptr != it_cb->second.second) { + LOG_INFO("Callback function on value change (%s) already exists, rewriting", path.to_string().c_str()); } cbValues[path].second = std::move(cb); - interface.registerValueChange(std::move(path)); + + auto msg = std::make_shared(path); + sendMsg(std::move(msg)); } void Settings::unregisterValueChange(const std::string &variableName, SettingsScope scope) { - auto path = EntryPath{.service = interface.ownerName(), .variable = variableName, .scope = scope}; + EntryPath path; + path.variable = variableName; + path.service = app->GetName(); + path.scope = scope; - auto callbacks = cbValues.find(path); - if (cbValues.end() == callbacks) { - log_debug("Callback function on value change (%s) does not exist", path.to_string().c_str()); + auto it_cb = cbValues.find(path); + if (cbValues.end() == it_cb) { + LOG_INFO("Callback function on value change (%s) does not exist", path.to_string().c_str()); } else { log_debug("[Settings::unregisterValueChange] %s", path.to_string().c_str()); - cbValues.erase(callbacks); + cbValues.erase(it_cb); } - interface.unregisterValueChange(std::move(path)); + + auto msg = std::make_shared(path); + sendMsg(std::move(msg)); + } + + void Settings::unregisterValueChange() + { + for (const auto &it_cb : cbValues) { + log_debug("[Settings::unregisterValueChange] %s", it_cb.first.to_string().c_str()); + auto msg = std::make_shared(it_cb.first); + sendMsg(std::move(msg)); + } + cbValues.clear(); + LOG_INFO("Unregistered all settings variable change on application (%s)", app->GetName().c_str()); } void Settings::setValue(const std::string &variableName, const std::string &variableValue, SettingsScope scope) { - auto path = EntryPath{.service = interface.ownerName(), .variable = variableName, .scope = scope}; - interface.setValue(path, variableValue); - getCache()->setValue(path, variableValue); + EntryPath path; + path.variable = variableName; + path.service = app->GetName(); + path.scope = scope; + auto msg = std::make_shared(path, variableValue); + sendMsg(std::move(msg)); + cache->setValue(path, variableValue); } std::string Settings::getValue(const std::string &variableName, SettingsScope scope) { - return getCache()->getValue({.service = interface.ownerName(), .variable = variableName, .scope = scope}); + EntryPath path; + path.variable = variableName; + path.service = app->GetName(); + path.scope = scope; + return cache->getValue(path); } - SettingsCache *Settings::getCache() + void Settings::getAllProfiles(OnAllProfilesRetrievedCallback cb) { - return SettingsCache::getInstance(); + if (nullptr == cbAllProfiles) { + sendMsg(std::make_shared()); + } + cbAllProfiles = std::move(cb); } + void Settings::setCurrentProfile(const std::string &profile) + { + sendMsg(std::make_shared(profile)); + } + + void Settings::addProfile(const std::string &profile) + { + sendMsg(std::make_shared(profile)); + } + + void Settings::registerProfileChange(ProfileChangedCallback cb) + { + if (nullptr != cbProfile) { + log_debug("Profile change callback already exists, overwritting"); + } + else { + sendMsg(std::make_shared()); + } + + cbProfile = std::move(cb); + } + + void Settings::unregisterProfileChange() + { + cbProfile = nullptr; + sendMsg(std::make_shared()); + } + + void Settings::getAllModes(OnAllModesRetrievedCallback cb) + { + if (nullptr == cbAllModes) { + sendMsg(std::make_shared()); + } + cbAllModes = std::move(cb); + } + + void Settings::setCurrentMode(const std::string &mode) + { + sendMsg(std::make_shared(mode)); + } + + void Settings::addMode(const std::string &mode) + { + sendMsg(std::make_shared(mode)); + } + + void Settings::registerModeChange(ModeChangedCallback cb) + { + if (nullptr != cbMode) { + log_debug("ModeChange callback allready set overwriting"); + } + else { + sendMsg(std::make_shared()); + } + cbMode = std::move(cb); + } + + void Settings::unregisterModeChange() + { + cbMode = nullptr; + sendMsg(std::make_shared()); + } } // namespace settings diff --git a/module-services/service-db/agents/settings/SettingsAgent.cpp b/module-services/service-db/agents/settings/SettingsAgent.cpp index eb7d2561f..83d9bd68e 100644 --- a/module-services/service-db/agents/settings/SettingsAgent.cpp +++ b/module-services/service-db/agents/settings/SettingsAgent.cpp @@ -11,6 +11,12 @@ namespace settings { + namespace DbPaths + { + constexpr auto phone_mode = "system/phone_mode"; + constexpr auto phone_profile = "system/phone_profile"; + } // namespace DbPaths + namespace factory { constexpr auto data_file = "personalization.json"; @@ -65,6 +71,29 @@ void SettingsAgent::registerMessages() std::bind(&SettingsAgent::handleRegisterOnVariableChange, this, _1)); parentService->connect(settings::Messages::UnregisterOnVariableChange(), std::bind(&SettingsAgent::handleUnregisterOnVariableChange, this, _1)); + // profile + parentService->connect(settings::Messages::RegisterOnProfileChange(), + std::bind(&SettingsAgent::handleRegisterProfileChange, this, _1)); + parentService->connect(settings::Messages::UnregisterOnProfileChange(), + std::bind(&SettingsAgent::handleUnregisterProfileChange, this, _1)); + parentService->connect(settings::Messages::SetCurrentProfile(), + std::bind(&SettingsAgent::handleSetCurrentProfile, this, _1)); + parentService->connect(settings::Messages::GetCurrentProfile(), + std::bind(&SettingsAgent::handleGetCurrentProfile, this, _1)); + parentService->connect(settings::Messages::AddProfile(), std::bind(&SettingsAgent::handleAddProfile, this, _1)); + parentService->connect(settings::Messages::ListProfiles(), std::bind(&SettingsAgent::handleListProfiles, this, _1)); + + // mode + parentService->connect(settings::Messages::RegisterOnModeChange(), + std::bind(&SettingsAgent::handleRegisterOnModeChange, this, _1)); + parentService->connect(settings::Messages::UnregisterOnModeChange(), + std::bind(&SettingsAgent::handleUnregisterOnModeChange, this, _1)); + parentService->connect(settings::Messages::SetCurrentMode(), + std::bind(&SettingsAgent::handleSetCurrentMode, this, _1)); + parentService->connect(settings::Messages::GetCurrentMode(), + std::bind(&SettingsAgent::handleGetCurrentMode, this, _1)); + parentService->connect(settings::Messages::AddMode(), std::bind(&SettingsAgent::handleAddMode, this, _1)); + parentService->connect(settings::Messages::ListModes(), std::bind(&SettingsAgent::handleListModes, this, _1)); } auto SettingsAgent::getDbInitString() -> const std::string @@ -108,6 +137,89 @@ auto SettingsAgent::dbUnregisterValueChange(const settings::EntryPath &path) -> settings::Statements::clearNotificationdRow, path.to_string().c_str(), path.service.c_str()); } +// db Profile +auto SettingsAgent::dbRegisterOnProfileChange(const std::string &service) -> bool +{ + return database->execute(settings::Statements::setNotification, settings::DbPaths::phone_profile, service.c_str()); +} +auto SettingsAgent::dbUnregisterOnProfileChange(const std::string &service) -> bool +{ + return database->execute( + settings::Statements::clearNotificationdRow, settings::DbPaths::phone_profile, service.c_str()); +} +auto SettingsAgent::dbSetCurrentProfile(const std::string &profile) -> bool +{ + return database->execute(settings::Statements::updateValue, profile.c_str(), settings::DbPaths::phone_profile); +} +auto SettingsAgent::dbGetCurrentProfile() -> std::string +{ + auto qProfile = database->query(settings::Statements::getValue, settings::DbPaths::phone_profile); + if (nullptr == qProfile || 1 != qProfile->getRowCount()) { + return std::string{}; + } + return (*qProfile)[0].getString(); +} +auto SettingsAgent::dbGetAllProfiles() -> std::list +{ + auto qProfiles = database->query(settings::Statements::getDictValue, settings::DbPaths::phone_profile); + if (nullptr == qProfiles || 0 == qProfiles->getRowCount()) { + return std::list{}; + } + std::list profiles; + do { + profiles.push_back((*qProfiles)[0].getString()); + } while (qProfiles->nextRow()); + return profiles; +} +auto SettingsAgent::dbAddProfile(const std::string &profile) -> bool +{ + return database->execute(settings::Statements::addDictValue, settings::DbPaths::phone_profile, profile.c_str()); +} + +// dbMode +auto SettingsAgent::dbRegisterOnModeChange(const std::string &service) -> bool +{ + return database->execute(settings::Statements::setNotification, settings::DbPaths::phone_mode, service.c_str()); +} + +auto SettingsAgent::dbUnregisterOnModeChange(const std::string &service) -> bool +{ + return database->execute( + settings::Statements::clearNotificationdRow, settings::DbPaths::phone_mode, service.c_str()); +} + +auto SettingsAgent::dbSetCurrentMode(const std::string &mode) -> bool +{ + return database->execute(settings::Statements::updateValue, mode.c_str(), settings::DbPaths::phone_mode); +} + +auto SettingsAgent::dbGetCurrentMode() -> std::string +{ + auto qMode = database->query(settings::Statements::getValue, settings::DbPaths::phone_mode); + if (nullptr == qMode || 1 != qMode->getRowCount()) { + return std::string{}; + } + return (*qMode)[0].getString(); +} + +auto SettingsAgent::dbGetAllModes() -> std::list +{ + auto qModes = database->query(settings::Statements::getDictValue, settings::DbPaths::phone_mode); + if (nullptr == qModes || 0 == qModes->getRowCount()) { + return std::list{}; + } + std::list modes; + do { + modes.push_back((*qModes)[0].getString()); + } while (qModes->nextRow()); + return modes; +} + +auto SettingsAgent::dbAddMode(const std::string &mode) -> bool +{ + return database->execute(settings::Statements::addDictValue, settings::DbPaths::phone_mode, mode.c_str()); +} + auto SettingsAgent::handleGetVariable(sys::Message *req) -> sys::MessagePointer { if (auto msg = dynamic_cast(req)) { @@ -180,3 +292,146 @@ auto SettingsAgent::handleUnregisterOnVariableChange(sys::Message *req) -> sys:: } return std::make_shared(); } + +// profile +auto SettingsAgent::handleRegisterProfileChange(sys::Message *req) -> sys::MessagePointer +{ + if (auto msg = dynamic_cast(req)) { + if (dbRegisterOnProfileChange(msg->sender)) { + profileChangedRecipients.insert(msg->sender); + auto msgCurrentProfile = std::make_shared(dbGetCurrentProfile()); + parentService->bus.sendUnicast(std::move(msgCurrentProfile), msg->sender); + } + } + return std::make_shared(); +} +auto SettingsAgent::handleUnregisterProfileChange(sys::Message *req) -> sys::MessagePointer +{ + if (auto msg = dynamic_cast(req)) { + if (dbUnregisterOnProfileChange(msg->sender)) { + profileChangedRecipients.erase(msg->sender); + } + } + return std::make_shared(); +} +auto SettingsAgent::handleSetCurrentProfile(sys::Message *req) -> sys::MessagePointer +{ + if (auto msg = dynamic_cast(req)) { + auto profile = msg->getProfileName(); + if (dbSetCurrentProfile(profile)) { + for (const auto &service : profileChangedRecipients) { + if (service != msg->sender) { + auto msgProfileChanged = std::make_shared(profile); + parentService->bus.sendUnicast(std::move(msgProfileChanged), service); + } + } + } + } + return std::make_shared(); +} +auto SettingsAgent::handleGetCurrentProfile(sys::Message *req) -> sys::MessagePointer +{ + if (nullptr != dynamic_cast(req)) { + auto service = profileChangedRecipients.find(req->sender); + if (profileChangedRecipients.end() != service) { + auto msgCurrentProfile = std::make_shared(dbGetCurrentProfile()); + parentService->bus.sendUnicast(std::move(msgCurrentProfile), *service); + } + } + return std::make_shared(); +} +auto SettingsAgent::handleAddProfile(sys::Message *req) -> sys::MessagePointer +{ + if (auto msg = dynamic_cast(req)) { + if (dbAddProfile(msg->getProfileName())) { + auto allProfiles = dbGetAllProfiles(); + for (const auto &service : profileChangedRecipients) { + if (service != req->sender) { + auto msgAllProfiles = std::make_shared(allProfiles); + parentService->bus.sendUnicast(std::move(msgAllProfiles), service); + } + } + } + } + return std::make_shared(); +} +auto SettingsAgent::handleListProfiles(sys::Message *req) -> sys::MessagePointer +{ + if (nullptr != dynamic_cast(req)) { + profileChangedRecipients.insert(req->sender); + auto msgAllProfiles = std::make_shared(dbGetAllProfiles()); + parentService->bus.sendUnicast(std::move(msgAllProfiles), req->sender); + } + return std::make_shared(); +} + +// mode +auto SettingsAgent::handleRegisterOnModeChange(sys::Message *req) -> sys::MessagePointer +{ + if (auto msg = dynamic_cast(req)) { + if (dbRegisterOnModeChange(msg->sender)) { + modeChangeRecipients.insert(msg->sender); + auto msgMode = std::make_shared(dbGetCurrentMode()); + parentService->bus.sendUnicast(std::move(msgMode), msg->sender); + } + } + return std::make_shared(); +} +auto SettingsAgent::handleUnregisterOnModeChange(sys::Message *req) -> sys::MessagePointer +{ + if (nullptr != dynamic_cast(req)) { + dbUnregisterOnModeChange(req->sender); + modeChangeRecipients.erase(req->sender); + } + return std::make_shared(); +} +auto SettingsAgent::handleSetCurrentMode(sys::Message *req) -> sys::MessagePointer +{ + if (auto msg = dynamic_cast(req)) { + if (auto newMode = msg->getProfileName(); dbGetCurrentMode() != newMode) { + if (dbSetCurrentMode(newMode)) { + for (const auto &service : modeChangeRecipients) { + if (service != msg->sender) { + auto msgModeChanged = std::make_shared(newMode); + parentService->bus.sendUnicast(std::move(msgModeChanged), service); + } + } + } + } + } + return std::make_shared(); +} +auto SettingsAgent::handleGetCurrentMode(sys::Message *req) -> sys::MessagePointer +{ + if (nullptr != dynamic_cast(req)) { + if (modeChangeRecipients.end() != modeChangeRecipients.find(req->sender)) { + auto msgMode = std::make_shared(dbGetCurrentMode()); + parentService->bus.sendUnicast(std::move(msgMode), req->sender); + } + } + return std::make_shared(); +} +auto SettingsAgent::handleAddMode(sys::Message *req) -> sys::MessagePointer +{ + if (auto msg = dynamic_cast(req)) { + if (dbAddMode(msg->getProfileName())) { + auto allModes = dbGetAllModes(); + for (const auto &service : modeChangeRecipients) { + if (service != msg->sender) { + auto msgAllModes = std::make_shared(allModes); + parentService->bus.sendUnicast(std::move(msgAllModes), service); + } + } + } + } + return std::make_shared(); +} +auto SettingsAgent::handleListModes(sys::Message *req) -> sys::MessagePointer +{ + if (nullptr != dynamic_cast(req)) { + modeChangeRecipients.insert(req->sender); + auto msgAllModes = std::make_shared(dbGetAllModes()); + parentService->bus.sendUnicast(std::move(msgAllModes), req->sender); + } + return std::make_shared(); +} diff --git a/module-services/service-db/agents/settings/SettingsAgent.hpp b/module-services/service-db/agents/settings/SettingsAgent.hpp index b00e86697..8878c3aaf 100644 --- a/module-services/service-db/agents/settings/SettingsAgent.hpp +++ b/module-services/service-db/agents/settings/SettingsAgent.hpp @@ -51,6 +51,20 @@ class SettingsAgent : public DatabaseAgent auto dbRegisterValueChange(const settings::EntryPath &path) -> bool; auto dbUnregisterValueChange(const settings::EntryPath &path) -> bool; + auto dbRegisterOnProfileChange(const std::string &service) -> bool; + auto dbUnregisterOnProfileChange(const std::string &service) -> bool; + auto dbSetCurrentProfile(const std::string &profile) -> bool; + auto dbGetCurrentProfile() -> std::string; + auto dbGetAllProfiles() -> std::list; + auto dbAddProfile(const std::string &profile) -> bool; + + auto dbRegisterOnModeChange(const std::string &service) -> bool; + auto dbUnregisterOnModeChange(const std::string &service) -> bool; + auto dbSetCurrentMode(const std::string &mode) -> bool; + auto dbGetCurrentMode() -> std::string; + auto dbGetAllModes() -> std::list; + auto dbAddMode(const std::string &mode) -> bool; + auto getDbInitString() -> const std::string override; // msg handlers @@ -59,4 +73,20 @@ class SettingsAgent : public DatabaseAgent auto handleSetVariable(sys::Message *req) -> sys::MessagePointer; auto handleRegisterOnVariableChange(sys::Message *req) -> sys::MessagePointer; auto handleUnregisterOnVariableChange(sys::Message *req) -> sys::MessagePointer; + + // profile + auto handleRegisterProfileChange(sys::Message *req) -> sys::MessagePointer; + auto handleUnregisterProfileChange(sys::Message *req) -> sys::MessagePointer; + auto handleSetCurrentProfile(sys::Message *req) -> sys::MessagePointer; + auto handleGetCurrentProfile(sys::Message *req) -> sys::MessagePointer; + auto handleAddProfile(sys::Message *req) -> sys::MessagePointer; + auto handleListProfiles(sys::Message *req) -> sys::MessagePointer; + + // mode + auto handleRegisterOnModeChange(sys::Message *req) -> sys::MessagePointer; + auto handleUnregisterOnModeChange(sys::Message *req) -> sys::MessagePointer; + auto handleSetCurrentMode(sys::Message *req) -> sys::MessagePointer; + auto handleGetCurrentMode(sys::Message *req) -> sys::MessagePointer; + auto handleAddMode(sys::Message *req) -> sys::MessagePointer; + auto handleListModes(sys::Message *req) -> sys::MessagePointer; }; diff --git a/module-services/service-db/agents/settings/SettingsCache.cpp b/module-services/service-db/agents/settings/SettingsCache.cpp index 59ac2f6fa..b74cd7612 100644 --- a/module-services/service-db/agents/settings/SettingsCache.cpp +++ b/module-services/service-db/agents/settings/SettingsCache.cpp @@ -1,61 +1,29 @@ -// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved. -// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md - #include #include namespace settings { - namespace - { - class SettingsCacheImpl : public SettingsCache - { - public: - static SettingsCacheImpl &get() - { - static SettingsCacheImpl instance; - return instance; - } - - const std::string &getValue(const EntryPath &path) const; - void setValue(const EntryPath &path, const std::string &value); - - private: - std::map settingsMap; - mutable cpp_freertos::MutexStandard settingsMutex; - }; - - const std::string &SettingsCacheImpl::getValue(const EntryPath &path) const - { - static const std::string empty; - cpp_freertos::LockGuard lock(settingsMutex); - auto pathIt = settingsMap.find(path); - if (settingsMap.end() != pathIt) { - return pathIt->second; - } - return empty; - } - - void SettingsCacheImpl::setValue(const EntryPath &path, const std::string &value) - { - cpp_freertos::LockGuard lock(settingsMutex); - settingsMap[path] = value; - } - } // namespace - SettingsCache *SettingsCache::getInstance() { - return &SettingsCacheImpl::get(); + static SettingsCache instance; + return &instance; } const std::string &SettingsCache::getValue(const EntryPath &path) const { - return SettingsCacheImpl::get().getValue(path); + static const std::string empty = ""; + cpp_freertos::LockGuard lock(settingsMutex); + auto pathIt = settingsMap.find(path); + if (settingsMap.end() != pathIt) { + return pathIt->second; + } + return empty; } void SettingsCache::setValue(const EntryPath &path, const std::string &value) { - return SettingsCacheImpl::get().setValue(path, value); + cpp_freertos::LockGuard lock(settingsMutex); + settingsMap[path] = value; } } // namespace settings diff --git a/module-services/service-db/agents/settings/SettingsProxy.cpp b/module-services/service-db/agents/settings/SettingsProxy.cpp deleted file mode 100644 index 207fc749f..000000000 --- a/module-services/service-db/agents/settings/SettingsProxy.cpp +++ /dev/null @@ -1,81 +0,0 @@ -// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved. -// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md - -#include -#include -#include -#include -#include -#include -#include -#include - -namespace settings -{ - - SettingsProxy::SettingsProxy(const service::ServiceProxy &interface) : service::ServiceProxy(interface) - {} - - SettingsProxy::~SettingsProxy() - { - deinit(); - } - - std::string SettingsProxy::ownerName() noexcept - { - return getService()->GetName(); - } - - void SettingsProxy::init(std::function onChangeHandler) - { - this->onChangeHandler = std::move(onChangeHandler); - - getService()->bus.channels.push_back(sys::BusChannel::ServiceDBNotifications); - getService()->connect(typeid(settings::Messages::VariableChanged), [this](sys::Message *req) { - if (auto msg = dynamic_cast(req)) { - onChange(msg->getPath(), msg->getValue().value_or("")); - } - return std::make_shared(); - }); - } - - void SettingsProxy::deinit() - { - if (isValid()) { - getService()->disconnect(typeid(settings::Messages::VariableChanged)); - } - } - - [[nodiscard]] bool SettingsProxy::isValid() const noexcept - { - return service::ServiceProxy::isValid(); - } - - void SettingsProxy::onChange(EntryPath path, std::string value) - { - if (onChangeHandler) { - onChangeHandler(std::move(path), std::move(value)); - } - } - - template auto message(sys::BusProxy &bus, Args... args) - { - bus.sendUnicast(std::make_shared(args...), service::name::db); - } - - void SettingsProxy::registerValueChange(EntryPath path) - { - message(getService()->bus, std::move(path)); - } - - void SettingsProxy::unregisterValueChange(EntryPath path) - { - message(getService()->bus, std::move(path)); - } - - void SettingsProxy::setValue(const EntryPath &path, const std::string &value) - { - message(getService()->bus, path, value); - } - -} // namespace settings diff --git a/module-services/service-db/service-db/EntryPath.hpp b/module-services/service-db/service-db/EntryPath.hpp deleted file mode 100644 index 64f5b50fd..000000000 --- a/module-services/service-db/service-db/EntryPath.hpp +++ /dev/null @@ -1,30 +0,0 @@ -// 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 -#include -#include - -namespace settings -{ - struct EntryPath - { - std::string mode = ""; - std::string service; - std::string profile = ""; - std::string variable; - SettingsScope scope; - - [[nodiscard]] auto to_string(std::string sep = "\\") const -> std::string - { - if (SettingsScope::Global == scope) { - return variable; - } - return mode + sep + service + sep + profile + sep + variable; - } - - void parse(const std::string &dbPath); - }; -} // namespace settings diff --git a/module-services/service-db/service-db/Settings.hpp b/module-services/service-db/service-db/Settings.hpp index 5bb26366e..70d406d92 100644 --- a/module-services/service-db/service-db/Settings.hpp +++ b/module-services/service-db/service-db/Settings.hpp @@ -1,11 +1,12 @@ -// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved. +// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved. // For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md #pragma once -#include "EntryPath.hpp" +#include +#include #include "SettingsScope.hpp" -#include "SettingsProxy.hpp" +#include "SettingsMessages.hpp" #include #include @@ -14,23 +15,23 @@ #include #include #include -#include namespace settings { class SettingsCache; - class Settings { public: using ValueChangedCallback = std::function; using ValueChangedCallbackWithName = std::function; + using ProfileChangedCallback = std::function; + using ModeChangedCallback = ProfileChangedCallback; + using ListOfProfiles = std::list; + using ListOfModes = ListOfProfiles; + using OnAllProfilesRetrievedCallback = std::function; + using OnAllModesRetrievedCallback = std::function; - Settings() = default; - virtual ~Settings(); - - void init(const service::ServiceProxy &interface); - void deinit(); + Settings(sys::Service *app, const std::string &dbAgentName = service::name::db, SettingsCache *cache = nullptr); void setValue(const std::string &variableName, const std::string &variableValue, @@ -43,17 +44,43 @@ namespace settings SettingsScope scope = SettingsScope::AppLocal); void unregisterValueChange(const std::string &variableName, SettingsScope scope = SettingsScope::AppLocal); /// unregisters all registered variables (both global and local) + void unregisterValueChange(); std::string getValue(const std::string &variableName, SettingsScope scope = SettingsScope::AppLocal); - SettingsCache *getCache(); + void getAllProfiles(OnAllProfilesRetrievedCallback cb); + void setCurrentProfile(const std::string &profile); + void addProfile(const std::string &profile); + void registerProfileChange(ProfileChangedCallback); + void unregisterProfileChange(); + + void getAllModes(OnAllModesRetrievedCallback cb); + void setCurrentMode(const std::string &mode); + void addMode(const std::string &mode); + void registerModeChange(ModeChangedCallback); + void unregisterModeChange(); private: - SettingsProxy interface; + std::string dbAgentName; + + std::shared_ptr app; + std::string serviceName; + std::string phoneMode; + std::string profile; + + SettingsCache *cache; using ValueCb = std::map>; - ValueCb cbValues; - - void handleVariableChanged(const EntryPath &path, const std::string &value); + ModeChangedCallback cbMode; + OnAllModesRetrievedCallback cbAllModes; + ProfileChangedCallback cbProfile; + OnAllProfilesRetrievedCallback cbAllProfiles; + void sendMsg(std::shared_ptr &&msg); + void registerHandlers(); + auto handleVariableChanged(sys::Message *req) -> sys::MessagePointer; + auto handleCurrentProfileChanged(sys::Message *req) -> sys::MessagePointer; + auto handleCurrentModeChanged(sys::Message *req) -> sys::MessagePointer; + auto handleProfileListResponse(sys::Message *req) -> sys::MessagePointer; + auto handleModeListResponse(sys::Message *req) -> sys::MessagePointer; }; } // namespace settings diff --git a/module-services/service-db/service-db/SettingsCache.hpp b/module-services/service-db/service-db/SettingsCache.hpp index b81cdcad7..c93e6123d 100644 --- a/module-services/service-db/service-db/SettingsCache.hpp +++ b/module-services/service-db/service-db/SettingsCache.hpp @@ -1,8 +1,7 @@ // 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 #include "SettingsMessages.hpp" #include @@ -14,6 +13,9 @@ namespace settings const std::string &getValue(const EntryPath &path) const; void setValue(const EntryPath &path, const std::string &value); static SettingsCache *getInstance(); - virtual ~SettingsCache() = default; + + private: + std::map settingsMap; + mutable cpp_freertos::MutexStandard settingsMutex; }; } // namespace settings diff --git a/module-services/service-db/service-db/SettingsMessages.hpp b/module-services/service-db/service-db/SettingsMessages.hpp index 83e13820d..6d542972c 100644 --- a/module-services/service-db/service-db/SettingsMessages.hpp +++ b/module-services/service-db/service-db/SettingsMessages.hpp @@ -5,16 +5,49 @@ #include #include -#include "EntryPath.hpp" +#include #include #include #include #include #include +#include namespace settings { + struct EntryPath + { + std::string mode; + std::string service; + std::string profile; + std::string variable; + SettingsScope scope; + + [[nodiscard]] auto to_string(std::string sep = "\\") const -> std::string + { + if (SettingsScope::Global == scope) { + return variable; + } + return mode + sep + service + sep + profile + sep + variable; + } + + void parse(const std::string &dbPath) + { + auto parts = utils::split(dbPath, "\\", false); + if (1 == parts.size()) { + variable = dbPath; + scope = SettingsScope::Global; + } + else { + mode = parts[0]; + service = parts[1]; + profile = parts[2]; + variable = parts[3]; + scope = SettingsScope::AppLocal; + } + } + }; bool operator<(const EntryPath &lhs, const EntryPath &rhs) noexcept; @@ -33,7 +66,7 @@ namespace settings public: Variable() = default; explicit Variable(EntryPath path, std::optional value = {}) - : path(std::move(path)), value(std::move(value)) + : SettingsMessage(), path(std::move(path)), value(std::move(value)) {} [[nodiscard]] auto getValue() const -> std::optional @@ -55,7 +88,7 @@ namespace settings { public: GetVariable() = default; - explicit GetVariable(EntryPath path) : Variable(std::move(path)) + explicit GetVariable(EntryPath path) : Variable(path) {} }; @@ -63,7 +96,7 @@ namespace settings { public: SetVariable() = default; - SetVariable(EntryPath path, std::string value) : Variable(std::move(path), value) + SetVariable(EntryPath path, std::string value) : Variable(path, value) {} }; @@ -71,7 +104,7 @@ namespace settings { public: RegisterOnVariableChange() = default; - explicit RegisterOnVariableChange(EntryPath path) : Variable(std::move(path)) + explicit RegisterOnVariableChange(EntryPath path) : Variable(path) {} }; @@ -79,7 +112,7 @@ namespace settings { public: UnregisterOnVariableChange() = default; - explicit UnregisterOnVariableChange(EntryPath path) : Variable(std::move(path)) + explicit UnregisterOnVariableChange(EntryPath path) : Variable(path) {} }; @@ -88,7 +121,7 @@ namespace settings public: VariableChanged() = default; explicit VariableChanged(EntryPath path, std::string value, std::string old_value) - : Variable(std::move(path), value), old_value(std::move(old_value)) + : Variable(path, value), old_value(std::move(old_value)) {} [[nodiscard]] auto getOldValue() const -> std::string @@ -100,6 +133,142 @@ namespace settings std::string old_value; }; + /// Profiles manipulation + class ListProfiles : public SettingsMessage + { + public: + [[nodiscard]] auto getProfiles() const -> std::set + { + return profiles; + } + + private: + std::set profiles; + }; + + class ProfileSettingsMessage : public SettingsMessage + { + public: + [[nodiscard]] auto getProfileName() const -> std::string + { + return profile; + } + + protected: + ProfileSettingsMessage() = default; + explicit ProfileSettingsMessage(std::string name) : SettingsMessage(), profile(std::move(name)) + {} + + protected: + std::string profile; + }; + + class SetCurrentProfile : public ProfileSettingsMessage + { + public: + SetCurrentProfile() = default; + explicit SetCurrentProfile(std::string profile) : ProfileSettingsMessage(profile) + {} + }; + + class AddProfile : public ProfileSettingsMessage + { + public: + AddProfile() = default; + explicit AddProfile(std::string profile) : ProfileSettingsMessage(profile) + {} + }; + + class GetCurrentProfile : public ProfileSettingsMessage + { + public: + GetCurrentProfile() = default; + explicit GetCurrentProfile(std::string profile) : ProfileSettingsMessage(profile) + {} + }; + + class RegisterOnProfileChange : public SettingsMessage + {}; + + class UnregisterOnProfileChange : public SettingsMessage + {}; + + class CurrentProfileChanged : public ProfileSettingsMessage + { + public: + CurrentProfileChanged() = default; + explicit CurrentProfileChanged(std::string profile) : ProfileSettingsMessage(profile) + {} + }; + + /// Modes manipulation + class ListModes : public SettingsMessage + { + public: + [[nodiscard]] auto getModes() const -> std::set + { + return modes; + } + + private: + std::set modes; + }; + + class Mode : public SettingsMessage + { + public: + [[nodiscard]] auto getModeName() const -> std::string + { + return mode; + } + + protected: + Mode() = default; + explicit Mode(std::string mode) : SettingsMessage(), mode(std::move(mode)) + {} + + protected: + std::string mode; + }; + + class SetCurrentMode : public ProfileSettingsMessage + { + public: + SetCurrentMode() = default; + explicit SetCurrentMode(std::string mode) : ProfileSettingsMessage(mode) + {} + }; + + class AddMode : public ProfileSettingsMessage + { + public: + AddMode() = default; + explicit AddMode(std::string mode) : ProfileSettingsMessage(mode) + {} + }; + + class GetCurrentMode : public ProfileSettingsMessage + { + public: + GetCurrentMode() = default; + explicit GetCurrentMode(std::string profile) : ProfileSettingsMessage(profile) + {} + }; + + class RegisterOnModeChange : public SettingsMessage + {}; + + class UnregisterOnModeChange : public SettingsMessage + {}; + + class CurrentModeChanged : public ProfileSettingsMessage + { + public: + CurrentModeChanged() = default; + explicit CurrentModeChanged(std::string profile) : ProfileSettingsMessage(profile) + {} + }; + class ValueResponse : sys::ResponseMessage { public: @@ -139,5 +308,54 @@ namespace settings EntryPath path; std::optional value; }; + + class ProfileResponse : public ValueResponse + { + public: + ProfileResponse() = default; + explicit ProfileResponse(std::string profile) : ValueResponse(profile) + {} + }; + + class ModeResponse : public ValueResponse + { + public: + ModeResponse() = default; + explicit ModeResponse(std::string mode) : ValueResponse(mode) + {} + }; + + class ListResponse : public SettingsMessage + { + public: + ListResponse() = default; + explicit ListResponse(std::list value) : SettingsMessage(), value(std::move(value)) + {} + + [[nodiscard]] auto getValue() const -> std::list + { + return value; + } + + protected: + std::list value; + }; + + class ProfileListResponse : public ListResponse + { + public: + ProfileListResponse() = default; + explicit ProfileListResponse(std::list profiles) : ListResponse(profiles) + {} + }; + + class ModeListResponse : public ListResponse + { + public: + ModeListResponse() = default; + explicit ModeListResponse(std::list modes) : ListResponse(modes) + {} + }; + } // namespace Messages } // namespace settings diff --git a/module-services/service-db/service-db/SettingsProxy.hpp b/module-services/service-db/service-db/SettingsProxy.hpp deleted file mode 100644 index 3867c2727..000000000 --- a/module-services/service-db/service-db/SettingsProxy.hpp +++ /dev/null @@ -1,30 +0,0 @@ -// 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 "EntryPath.hpp" -#include "Service/ServiceProxy.hpp" -#include - -namespace settings -{ - class SettingsProxy : private service::ServiceProxy - { - public: - SettingsProxy() = default; - ~SettingsProxy(); - explicit SettingsProxy(const service::ServiceProxy &interface); - void init(std::function onChangeHandler); - void deinit(); - [[nodiscard]] bool isValid() const noexcept; - - void onChange(EntryPath path, std::string value); - void registerValueChange(EntryPath path); - void unregisterValueChange(EntryPath path); - void setValue(const EntryPath &path, const std::string &value); - [[nodiscard]] std::string ownerName() noexcept; - - private: - std::function onChangeHandler; - }; -} // namespace settings diff --git a/module-services/service-db/test/CMakeLists.txt b/module-services/service-db/test/CMakeLists.txt index 3e04e4d10..761a30dc5 100644 --- a/module-services/service-db/test/CMakeLists.txt +++ b/module-services/service-db/test/CMakeLists.txt @@ -32,4 +32,3 @@ add_catch2_executable( ) add_subdirectory(test-settings) -add_subdirectory(test-settings-Settings) diff --git a/module-services/service-db/test/test-service-db-settings-messages.cpp b/module-services/service-db/test/test-service-db-settings-messages.cpp index bfa151fce..582ea00a6 100644 --- a/module-services/service-db/test/test-service-db-settings-messages.cpp +++ b/module-services/service-db/test/test-service-db-settings-messages.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved. +// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved. // For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md #include // for Section, SourceLineInfo, SECTION, SectionInfo, StringRef, TEST_CASE @@ -83,6 +83,24 @@ namespace settings } return std::make_shared(); }; + + sys::MessagePointer handleListProfiles(sys::Message *req) + { + if (dynamic_cast(req) != nullptr) { + std::list profiles = {"silent", "loud"}; + return std::make_shared(profiles); + } + return std::make_shared(); + }; + + sys::MessagePointer handleListModes(sys::Message *req) + { + if (dynamic_cast(req) != nullptr) { + std::list modes = {"mode1", "mode2"}; + return std::make_shared(modes); + } + return std::make_shared(); + }; }; } // namespace settings @@ -107,4 +125,32 @@ TEST_CASE("Settings Messages") {"mode", "service", "profile", "variable", settings::SettingsScope::AppLocal})), "db-worker"); } + + SECTION("Send profile messages") + { + settings::Service settings("settings"); + settings.InitHandler(); + + settings.bus.sendUnicast(std::make_shared(), "settings"); + + settings.bus.sendUnicast(std::make_shared("new-profile"), "settings"); + + settings.bus.sendUnicast(std::make_shared(), "settings"); + + settings.bus.sendUnicast(std::make_shared("profile"), "settings"); + } + + SECTION("Send mode messages") + { + settings::Service settings("settings"); + settings.InitHandler(); + + settings.bus.sendUnicast(std::make_shared(), "settings"); + + settings.bus.sendUnicast(std::make_shared(), "settings"); + + settings.bus.sendUnicast(std::make_shared("new-mode"), "settings"); + + settings.bus.sendUnicast(std::make_shared("mode"), "settings"); + } } diff --git a/module-services/service-db/test/test-settings-Settings/CMakeLists.txt b/module-services/service-db/test/test-settings-Settings/CMakeLists.txt deleted file mode 100644 index 3a403f2ee..000000000 --- a/module-services/service-db/test/test-settings-Settings/CMakeLists.txt +++ /dev/null @@ -1,17 +0,0 @@ -# service-db tests -add_catch2_executable( - NAME - settings-Settings - SRCS - main.cpp - test-settings-Interface.cpp - test-settings-Settings.cpp - ../../agents/settings/Settings.cpp - ../../EntryPath.cpp - INCLUDE - ${CMAKE_SOURCE_DIR}/module-sys - ${CMAKE_SOURCE_DIR}/source - ${CMAKE_SOURCE_DIR}/module-services/service-db - ${CMAKE_SOURCE_DIR}/module-utils/ - DEPS -) diff --git a/module-services/service-db/test/test-settings-Settings/main.cpp b/module-services/service-db/test/test-settings-Settings/main.cpp deleted file mode 100644 index 24584da01..000000000 --- a/module-services/service-db/test/test-settings-Settings/main.cpp +++ /dev/null @@ -1,5 +0,0 @@ -// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved. -// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md - -#define CATCH_CONFIG_MAIN -#include diff --git a/module-services/service-db/test/test-settings-Settings/test-settings-Interface.cpp b/module-services/service-db/test/test-settings-Settings/test-settings-Interface.cpp deleted file mode 100644 index b20dd2a68..000000000 --- a/module-services/service-db/test/test-settings-Settings/test-settings-Interface.cpp +++ /dev/null @@ -1,72 +0,0 @@ -// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved. -// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md - -#include -#include -#include - -namespace sys -{ - // mockup - class Service - {}; - -} // namespace sys - -class Interface_imp : public service::ServiceProxy -{ - public: - using ServiceProxy::getService; - Interface_imp() = default; - explicit Interface_imp(std::weak_ptr s) : service::ServiceProxy(std::move(s)) - {} -}; - -TEST_CASE("Interface - not initialized") -{ - SECTION("base api") - { - auto interface = service::ServiceProxy(); - REQUIRE(!interface.isValid()); - } - - SECTION("inherited api") - { - auto interface = Interface_imp(); - REQUIRE_THROWS_AS(interface.getService(), std::runtime_error); - } -} - -TEST_CASE("Interface - initialized") -{ - auto service = std::make_shared(); - auto interface = Interface_imp(service); - REQUIRE(interface.isValid()); - REQUIRE_NOTHROW(interface.getService()); -} - -TEST_CASE("Interface - expired") -{ - Interface_imp *interface; - std::shared_ptr expired; - { - auto service = std::make_shared(); - interface = new Interface_imp(service); - } - REQUIRE(!interface->isValid()); - REQUIRE_THROWS_AS(interface->getService(), std::runtime_error); - delete interface; -} - -TEST_CASE("Interface - copied") -{ - auto service = std::make_shared(); - auto interface = Interface_imp(service); - auto interface2 = interface; - - REQUIRE(interface.isValid()); - REQUIRE_NOTHROW(interface.getService()); - REQUIRE(interface2.isValid()); - REQUIRE_NOTHROW(interface2.getService()); - REQUIRE(interface2.getService() == interface.getService()); -} diff --git a/module-services/service-db/test/test-settings-Settings/test-settings-Settings.cpp b/module-services/service-db/test/test-settings-Settings/test-settings-Settings.cpp deleted file mode 100644 index c0806423d..000000000 --- a/module-services/service-db/test/test-settings-Settings/test-settings-Settings.cpp +++ /dev/null @@ -1,91 +0,0 @@ -// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved. -// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md - -#include -#include -#include "module-services/service-db/service-db/SettingsCache.hpp" -#include - -/// stub -namespace settings -{ - SettingsProxy::~SettingsProxy() - {} - SettingsProxy::SettingsProxy(const service::ServiceProxy &interface) : service::ServiceProxy(interface) - {} - void SettingsProxy::init(std::function onChangeHandler) - { - this->onChangeHandler = std::move(onChangeHandler); - } - void SettingsProxy::deinit() - {} - - void SettingsProxy::onChange(EntryPath path, std::string value) - { - if (onChangeHandler) { - onChangeHandler(std::move(path), std::move(value)); - } - }; - bool SettingsProxy::isValid() const noexcept - { - return true; - } - void SettingsProxy::registerValueChange(EntryPath){}; - void SettingsProxy::unregisterValueChange(EntryPath){}; - void SettingsProxy::setValue(const EntryPath &path, const std::string &value){}; - std::string SettingsProxy::ownerName() noexcept - { - return ""; - } - - const std::string &SettingsCache::getValue(const EntryPath &path) const - { - static const std::string val; - return val; - } - void SettingsCache::setValue(const EntryPath &path, const std::string &value) - {} - - SettingsCache *SettingsCache::getInstance() - { - static SettingsCache s; - return &s; - } - -} // namespace settings - -/// TODO shall we warn here... on uninitialized settings? -TEST_CASE("Settings - not initialized") -{ - settings::Settings setting; - SECTION("Not initialized settings") - { - auto val = setting.getValue("lol"); - REQUIRE(val.empty()); - } - - SECTION("dead initialized settings") - { - auto val = setting.getValue("lol"); - REQUIRE(val.empty()); - } -} - -TEST_CASE("Settings - initialized") -{ - /// this will require stubbing - SECTION("get Value - not exists") - {} - - SECTION("get Value - exists") - {} - - SECTION("get Value - different type that expected") - {} - - SECTION("set value - no value") - {} - - SECTION("set value - override") - {} -} diff --git a/module-services/service-db/test/test-settings/CMakeLists.txt b/module-services/service-db/test/test-settings/CMakeLists.txt index 8cd272c0e..1130bdf23 100644 --- a/module-services/service-db/test/test-settings/CMakeLists.txt +++ b/module-services/service-db/test/test-settings/CMakeLists.txt @@ -11,5 +11,7 @@ add_catch2_executable( module-audio service-cellular module-cellular + iosyscalls DEPS + disk_image ) 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 763d6b764..f2c4d20ae 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 @@ -1,4 +1,4 @@ -// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved. +// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved. // For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md #include @@ -27,60 +27,105 @@ TEST_CASE("SettingsApi") std::shared_ptr varWritter; std::shared_ptr varReader; std::shared_ptr testVar; + std::shared_ptr profWritter; + std::shared_ptr profReader; + std::shared_ptr testProf; + std::shared_ptr modeWritter; + std::shared_ptr modeReader; + std::shared_ptr testMode; std::shared_ptr testStart; - std::shared_ptr postMortemSetting; + manager->StartSystem( + nullptr, + [manager, + &varWritter, + &varReader, + &testVar, + &profWritter, + &profReader, + &testProf, + &modeWritter, + &modeReader, + &testMode, + &testStart]() { + // preliminary + testStart = std::make_shared(); + testStart->lock(); + std::cout << "start thr_id: " << std::this_thread::get_id() << std::endl << std::flush; + auto ret = sys::SystemManager::RunSystemService( + std::make_shared(service::name::evt_manager), manager.get()); + ret &= sys::SystemManager::RunSystemService(std::make_shared(), manager.get()); - manager->StartSystem(nullptr, [manager, &varWritter, &varReader, &testVar, &testStart, &postMortemSetting]() { - // preliminary - testStart = std::make_shared(); - testStart->lock(); - std::cout << "start thr_id: " << std::this_thread::get_id() << std::endl << std::flush; - 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"); - varWritter = std::make_shared("writterVar"); - varReader = std::make_shared("readerVar"); + ret &= sys::SystemManager::RunSystemService(varWritter, manager.get()); + ret &= sys::SystemManager::RunSystemService(varReader, manager.get()); - postMortemSetting = varWritter->getSettings(); + testVar = std::make_shared("appTest", varWritter, varReader, testStart); + ret &= sys::SystemManager::RunSystemService(testVar, manager.get()); - ret &= sys::SystemManager::RunSystemService(varWritter, manager.get()); - ret &= sys::SystemManager::RunSystemService(varReader, manager.get()); + profWritter = std::make_shared("writterProf"); + profReader = std::make_shared("readerProf"); - testVar = std::make_shared("appTest", varWritter, varReader, testStart); - ret &= sys::SystemManager::RunSystemService(testVar, manager.get()); + ret &= sys::SystemManager::RunSystemService(profWritter, manager.get()); + ret &= sys::SystemManager::RunSystemService(profReader, manager.get()); - std::cout << "koniec start thr_id: " << std::this_thread::get_id() << std::endl << std::flush; - testStart->unlock(); - auto msgStart = std::make_shared(); - manager->bus.sendUnicast(std::move(msgStart), "appTest"); + testProf = std::make_shared( + "appTestProfile", profWritter, profReader, testStart); + ret &= sys::SystemManager::RunSystemService(testProf, manager.get()); - msgStart = std::make_shared(); - manager->bus.sendUnicast(std::move(msgStart), "appTestProfile"); + modeWritter = std::make_shared("writterMode"); + modeReader = std::make_shared("readerMode"); - msgStart = std::make_shared(); - manager->bus.sendUnicast(std::move(msgStart), "appTestMode"); + ret &= sys::SystemManager::RunSystemService(modeWritter, manager.get()); + ret &= sys::SystemManager::RunSystemService(modeReader, manager.get()); - return ret; - }); + testMode = + std::make_shared("appTestMode", modeWritter, modeReader, testStart); + ret &= sys::SystemManager::RunSystemService(testMode, manager.get()); - try { - // start application - cpp_freertos::Thread::StartScheduler(); + std::cout << "koniec start thr_id: " << std::this_thread::get_id() << std::endl << std::flush; + testStart->unlock(); + auto msgStart = std::make_shared(); + manager->bus.sendUnicast(std::move(msgStart), "appTest"); - // check the results - std::cout << "testVar values:" << std::endl << std::flush; - for (const auto &s : testVar->v) { - std::cout << s << std::endl << std::flush; - } - REQUIRE(testVar->v.size() == 3); - REQUIRE(testVar->v[1] == testVar->v[0] + "1"); - REQUIRE(testVar->v[2] == testVar->v[1] + "2"); + msgStart = std::make_shared(); + manager->bus.sendUnicast(std::move(msgStart), "appTestProfile"); + + msgStart = std::make_shared(); + manager->bus.sendUnicast(std::move(msgStart), "appTestMode"); + + return ret; + }); + + // start application + cpp_freertos::Thread::StartScheduler(); + + // check the results + std::cout << "testVar values:" << std::endl << std::flush; + for (auto s : testVar->v) { + std::cout << s << std::endl << std::flush; } - catch (std::exception &error) { - std::cout << error.what() << std::endl; - exit(1); + REQUIRE(testVar->v.size() == 3); + REQUIRE(testVar->v[1] == testVar->v[0] + "1"); + REQUIRE(testVar->v[2] == testVar->v[1] + "2"); + + // check the result + std::cout << "testProf values:" << std::endl << std::flush; + for (auto s : testProf->v) { + std::cout << s << std::endl << std::flush; } + REQUIRE(testProf->v[1] == testProf->v[0] + "1"); + REQUIRE(testProf->v[2] == testProf->v[0] + "12"); + REQUIRE(testProf->v[3] == "other"); + + std::cout << "testMode values:" << std::endl << std::flush; + for (auto s : testMode->v) { + std::cout << s << std::endl << std::flush; + } + REQUIRE(testMode->v[1] == testMode->v[0] + "1"); + REQUIRE(testMode->v[2] == testMode->v[0] + "12"); + REQUIRE(testMode->v[3] == "other"); } } 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 c67b90232..0f23d2b7a 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 @@ -66,21 +66,6 @@ namespace settings std::string last_v; std::vector v; - void setState(State state) - { - printf("state change: [%s]->[%s]\n", - std::string(magic_enum::enum_name(this->state)).c_str(), - std::string(magic_enum::enum_name(state)).c_str()); - this->state = state; - } - bool isState(State cmp) - { - printf("state compare: [%s]->[%s]\n", - std::string(magic_enum::enum_name(this->state)).c_str(), - std::string(magic_enum::enum_name(state)).c_str()); - return this->state == cmp; - } - AppTest(std::string name, std::shared_ptr setter, std::shared_ptr getter, @@ -90,7 +75,7 @@ namespace settings {} sys::ReturnCodes InitHandler() override { - setState(State::Unk); + state = State::Unk; return sys::ReturnCodes::Success; } sys::ReturnCodes DeinitHandler() override @@ -103,48 +88,48 @@ namespace settings if (nullptr != dynamic_cast(msg)) { testStart->lock(); testStart->unlock(); - if (!isState(State::Unk)) { + if (state != State::Unk) { closeSystem(); } else { - setState(State::Start); + state = State::Start; auto msg = std::make_shared("brightness", "none"); bus.sendUnicast(std::move(msg), getter->GetName()); } } else if (nullptr != dynamic_cast(msg)) { - if (isState(State::Start)) { - setState(State::Register); + if (state == State::Start) { + state = State::Register; } } else if (auto m = dynamic_cast(msg)) { - if (isState(State::Register)) { - setState(State::RegisterStartVal); + if (state == State::Register) { + state = State::RegisterStartVal; v.push_back(m->value); auto msg = std::make_shared("brightness", v[0] + "1"); bus.sendUnicast(std::move(msg), setter->GetName()); } - else if (isState(State::RegisterSetVal)) { + else if (state == State::RegisterSetVal) { if (m->value == v[0] + "1") { v.push_back(m->value); auto msg = std::make_shared("brightness", "empty"); bus.sendUnicast(std::move(msg), getter->GetName()); - setState(State::UnregisterWait); + state = State::UnregisterWait; } } } else if (nullptr != dynamic_cast(msg)) { - if (isState(State::UnregisterWait)) { - setState(State::Unregister); + if (state == State::UnregisterWait) { + state = State::Unregister; auto msg = std::make_shared("brightness", v.back() + "2"); bus.sendUnicast(std::move(msg), setter->GetName()); } } else if (auto m = dynamic_cast(msg)) { - if (isState(State::RegisterStartVal)) { - setState(State::RegisterSetVal); + if (state == State::RegisterStartVal) { + state = State::RegisterSetVal; } - else if (isState(State::Unregister)) { + else if (state == State::Unregister) { std::this_thread::sleep_for(std::chrono::milliseconds(200)); v.push_back(m->value); auto msg = std::make_shared(); @@ -152,7 +137,7 @@ namespace settings } } else if (nullptr != dynamic_cast(msg)) { - if (isState(State::Unregister)) { + if (state == State::Unregister) { closeSystem(); } } @@ -183,69 +168,69 @@ namespace settings if (nullptr != dynamic_cast(msg)) { testStart->lock(); testStart->unlock(); - if (!isState(State::Unk)) { + if (state != State::Unk) { closeSystem(); } else { - setState(State::Start); + state = State::Start; auto msg = std::make_shared(); bus.sendUnicast(std::move(msg), getter->GetName()); } } else if (nullptr != dynamic_cast(msg)) { - if (isState(State::Start)) { - setState(State::Register); + if (state == State::Start) { + state = State::Register; } } else if (auto m = dynamic_cast(msg)) { - if (isState(State::Register)) { - setState(State::RegisterStartVal); + if (state == State::Register) { + state = State::RegisterStartVal; v.push_back(m->name); auto msg = std::make_shared(m->name + "1"); bus.sendUnicast(std::move(msg), setter->GetName()); } - else if (isState(State::RegisterSetVal)) { + else if (state == State::RegisterSetVal) { if (m->name == v[0] + "1") { v.push_back(m->name); auto msg = std::make_shared(); bus.sendUnicast(std::move(msg), getter->GetName()); - setState(State::UnregisterWait); + state = State::UnregisterWait; } } } else if (nullptr != dynamic_cast(msg)) { - if (isState(State::UnregisterWait)) { - setState(State::Unregister); + if (state == State::UnregisterWait) { + state = State::Unregister; auto msg = std::make_shared(v.back() + "2"); bus.sendUnicast(std::move(msg), setter->GetName()); } } else if (auto m = dynamic_cast(msg)) { - if (isState(State::RegisterStartVal)) { - setState(State::RegisterSetVal); + if (state == State::RegisterStartVal) { + state = State::RegisterSetVal; } - else if (isState(State::Unregister)) { + else if (state == State::Unregister) { v.push_back(m->name); auto msg = std::make_shared(); bus.sendUnicast(std::move(msg), getter->GetName()); } } else if (nullptr != dynamic_cast(msg)) { - if (isState(State::Unregister)) { - setState(State::RegisterAllWait); + if (state == State::Unregister) { + state = State::RegisterAllWait; } } else if (auto m = dynamic_cast(msg)) { - if (isState(State::RegisterAllWait)) { - setState(State::RegisterAll); + if (state == State::RegisterAllWait) { + state = State::RegisterAll; for (auto prof : m->profiles) { v.push_back(prof); } auto msg = std::make_shared("other"); bus.sendUnicast(std::move(msg), setter->GetName()); } - else if (isState(State::RegisterAllAddWait)) { - setState(State::RegisterAllAdd); + else if (state == State::RegisterAllAddWait) { + state = State::RegisterAllAdd; for (auto prof : m->profiles) { v.push_back(prof); } @@ -255,12 +240,12 @@ namespace settings } } else if (nullptr != dynamic_cast(msg)) { - if (isState(State::RegisterAll)) { - setState(State::RegisterAllAddWait); + if (state == State::RegisterAll) { + state = State::RegisterAllAddWait; } } else if (nullptr != dynamic_cast(msg)) { - if (isState(State::RegisterAllAdd)) { + if (state == State::RegisterAllAdd) { closeSystem(); } } diff --git a/module-services/service-db/test/test-settings/test-service-db-settings-testservices.hpp b/module-services/service-db/test/test-settings/test-service-db-settings-testservices.hpp index 84bd3e205..9aebee407 100644 --- a/module-services/service-db/test/test-settings/test-service-db-settings-testservices.hpp +++ b/module-services/service-db/test/test-settings/test-service-db-settings-testservices.hpp @@ -1,8 +1,6 @@ -// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved. +// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved. // For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md -#include - namespace settings { class MyService : public sys::Service @@ -10,6 +8,7 @@ namespace settings public: MyService(const std::string &name) : sys::Service(name) { + mySettings = std::make_shared(this); } std::shared_ptr mySettings; std::vector valChanged; @@ -60,15 +59,11 @@ namespace settings } sys::ReturnCodes InitHandler() override { - std::cout << "InitHandler thr_id: " << std::this_thread::get_id() << "name: " << GetName() << std::endl - << std::flush; - mySettings = std::make_shared(); - mySettings->init(service::ServiceProxy(shared_from_this())); + std::cout << "inithandler thr_id: " << std::this_thread::get_id() << std::endl << std::flush; return sys::ReturnCodes::Success; } sys::ReturnCodes DeinitHandler() override { - mySettings->deinit(); std::cout << "deinithandler thr_id: " << std::this_thread::get_id() << std::endl << std::flush; return sys::ReturnCodes::Success; } @@ -76,11 +71,115 @@ namespace settings { return sys::ReturnCodes::Success; } + }; - std::shared_ptr getSettings() + class ServiceProfile : public MyService + { + public: + ServiceProfile(const std::string &name) : MyService(name) + {} + settings::Settings::ListOfProfiles profiles; + std::string profile; + sys::MessagePointer DataReceivedHandler(sys::DataMessage *req, sys::ResponseMessage *resp) override { - return mySettings; + if (auto msg = dynamic_cast(req)) { + debug("ReqRegProfileChg", msg->name, msg->value); + whoRequestedNotifyOnChange = msg->sender; + mySettings->registerProfileChange(([this](const std::string &profile) { + this->profile = profile; + auto cnf = std::make_shared(profile); + bus.sendUnicast(std::move(cnf), whoRequestedNotifyOnChange); + })); + auto cnf = std::make_shared(); + bus.sendUnicast(std::move(cnf), whoRequestedNotifyOnChange); + } + else if (auto msg = dynamic_cast(req)) { + // unregister + debug("ReqUnRegProfileChg", msg->name, msg->value); + mySettings->unregisterProfileChange(); + auto cnf = std::make_shared(); + bus.sendUnicast(std::move(cnf), msg->sender); + } + else if (auto msg = dynamic_cast(req)) { + // set value + debug("ReqSetCurrentProfile", msg->name, msg->value); + mySettings->setCurrentProfile(msg->name); + auto cnf = std::make_shared(msg->name); + bus.sendUnicast(std::move(cnf), msg->sender); + } + else if (auto msg = dynamic_cast(req)) { + debug("ReqGetAllProfiles", msg->name, msg->value); + mySettings->getAllProfiles(([this](const settings::Settings::ListOfProfiles &profiles) { + this->profiles = profiles; + auto cnf = std::make_shared(profiles); + bus.sendUnicast(std::move(cnf), whoRequestedNotifyOnChange); + })); + auto cnf = std::make_shared(); + bus.sendUnicast(std::move(cnf), msg->sender); + } + else if (auto msg = dynamic_cast(req)) { + debug("ReqAddProfile", msg->name, msg->value); + mySettings->addProfile(msg->name); + auto cnf = std::make_shared(msg->name); + bus.sendUnicast(std::move(cnf), msg->sender); + } + + return std::make_shared(); } }; + class ServiceMode : public MyService + { + public: + ServiceMode(const std::string &name) : MyService(name) + {} + settings::Settings::ListOfModes modes; + std::string mode; + sys::MessagePointer DataReceivedHandler(sys::DataMessage *req, sys::ResponseMessage *resp) override + { + if (auto msg = dynamic_cast(req)) { + debug("ReqRegProfileChg", msg->name, msg->value); + whoRequestedNotifyOnChange = msg->sender; + mySettings->registerModeChange(([this](const std::string &mode) { + this->mode = mode; + auto cnf = std::make_shared(mode); + bus.sendUnicast(std::move(cnf), whoRequestedNotifyOnChange); + })); + auto cnf = std::make_shared(); + bus.sendUnicast(std::move(cnf), whoRequestedNotifyOnChange); + } + else if (auto msg = dynamic_cast(req)) { + // unregister + debug("ReqUnRegProfileChg", msg->name, msg->value); + mySettings->unregisterModeChange(); + auto cnf = std::make_shared(); + bus.sendUnicast(std::move(cnf), msg->sender); + } + else if (auto msg = dynamic_cast(req)) { + // set value + debug("ReqSetCurrentProfile", msg->name, msg->value); + mySettings->setCurrentMode(msg->name); + auto cnf = std::make_shared(msg->name); + bus.sendUnicast(std::move(cnf), msg->sender); + } + else if (auto msg = dynamic_cast(req)) { + debug("ReqGetAllProfiles", msg->name, msg->value); + mySettings->getAllModes(([this](const settings::Settings::ListOfModes &modes) { + this->modes = modes; + auto cnf = std::make_shared(modes); + bus.sendUnicast(std::move(cnf), whoRequestedNotifyOnChange); + })); + auto cnf = std::make_shared(); + bus.sendUnicast(std::move(cnf), msg->sender); + } + else if (auto msg = dynamic_cast(req)) { + debug("ReqAddProfile", msg->name, msg->value); + mySettings->addMode(msg->name); + auto cnf = std::make_shared(msg->name); + bus.sendUnicast(std::move(cnf), msg->sender); + } + + return std::make_shared(); + } + }; } // namespace settings diff --git a/module-services/service-desktop/ServiceDesktop.cpp b/module-services/service-desktop/ServiceDesktop.cpp index f4568b221..2f86ac059 100644 --- a/module-services/service-desktop/ServiceDesktop.cpp +++ b/module-services/service-desktop/ServiceDesktop.cpp @@ -68,6 +68,8 @@ ServiceDesktop::ServiceDesktop() bus.channels.push_back(sys::BusChannel::PhoneLockChanges); updateOS = std::make_unique(this); + settings = std::make_unique(this); + usbSecurityModel = std::make_unique(this, settings.get()); } ServiceDesktop::~ServiceDesktop() @@ -77,10 +79,6 @@ ServiceDesktop::~ServiceDesktop() sys::ReturnCodes ServiceDesktop::InitHandler() { - - settings = std::make_unique(); - settings->init(service::ServiceProxy(shared_from_this())); - usbSecurityModel = std::make_unique(this, settings.get()); desktopWorker = std::make_unique(this, *usbSecurityModel.get()); const bool ret = desktopWorker->init({{sdesktop::RECEIVE_QUEUE_BUFFER_NAME, sizeof(std::string *), sdesktop::cdc_queue_len}, @@ -297,7 +295,6 @@ sys::ReturnCodes ServiceDesktop::InitHandler() sys::ReturnCodes ServiceDesktop::DeinitHandler() { - settings->deinit(); desktopWorker->deinit(); return sys::ReturnCodes::Success; } diff --git a/module-services/service-desktop/endpoints/developerMode/DeveloperModeHelper.cpp b/module-services/service-desktop/endpoints/developerMode/DeveloperModeHelper.cpp index 034a63300..3c701ee82 100644 --- a/module-services/service-desktop/endpoints/developerMode/DeveloperModeHelper.cpp +++ b/module-services/service-desktop/endpoints/developerMode/DeveloperModeHelper.cpp @@ -2,7 +2,6 @@ // For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md #include "DeveloperModeHelper.hpp" -#include "service-db/SettingsMessages.hpp" #include #include diff --git a/module-services/service-evtmgr/EventManager.cpp b/module-services/service-evtmgr/EventManager.cpp index e843e363a..e3505c096 100644 --- a/module-services/service-evtmgr/EventManager.cpp +++ b/module-services/service-evtmgr/EventManager.cpp @@ -55,11 +55,13 @@ namespace } // namespace EventManager::EventManager(const std::string &name) - : sys::Service(name, "", stackDepth), loggerTimer{sys::TimerFactory::createPeriodicTimer( - this, - loggerTimerName, - std::chrono::milliseconds{loggerDelayMs}, - [this](sys::Timer & /*timer*/) { dumpLogsToFile(); })}, + : sys::Service(name, "", stackDepth), + settings(std::make_shared(this)), loggerTimer{sys::TimerFactory::createPeriodicTimer( + this, + loggerTimerName, + std::chrono::milliseconds{loggerDelayMs}, + [this](sys::Timer & /*timer*/) { dumpLogsToFile(); })}, + screenLightControl(std::make_unique(settings, this)), Vibra(std::make_unique(this)) { LOG_INFO("[%s] Initializing", name.c_str()); @@ -207,8 +209,6 @@ sys::MessagePointer EventManager::DataReceivedHandler(sys::DataMessage *msgl, sy // Invoked during initialization sys::ReturnCodes EventManager::InitHandler() { - settings->init(service::ServiceProxy(shared_from_this())); - screenLightControl = std::make_unique(settings, this); connect(sdesktop::developerMode::DeveloperModeRequest(), [&](sys::Message *msg) { using namespace sdesktop::developerMode; @@ -329,8 +329,6 @@ sys::ReturnCodes EventManager::InitHandler() sys::ReturnCodes EventManager::DeinitHandler() { - settings->deinit(); - EventWorker->close(); EventWorker.reset(); EventWorker = nullptr; diff --git a/module-services/service-evtmgr/service-evtmgr/EventManager.hpp b/module-services/service-evtmgr/service-evtmgr/EventManager.hpp index 1241c38b8..d02d16598 100644 --- a/module-services/service-evtmgr/service-evtmgr/EventManager.hpp +++ b/module-services/service-evtmgr/service-evtmgr/EventManager.hpp @@ -38,7 +38,7 @@ class EventManager : public sys::Service void toggleTorchOnOff(); void toggleTorchColor(); - std::shared_ptr settings = std::make_shared(); + std::shared_ptr settings; sys::TimerHandle loggerTimer; sys::TimerHandle keypadLightTimer; bsp::keypad_backlight::State keypadLightState{bsp::keypad_backlight::State::off}; diff --git a/module-sys/Service/Common.hpp b/module-sys/Service/Common.hpp index 407a1bdc9..2737669dc 100644 --- a/module-sys/Service/Common.hpp +++ b/module-sys/Service/Common.hpp @@ -3,6 +3,7 @@ #pragma once +#include "FreeRTOSConfig.h" #include "SystemReturnCodes.hpp" namespace sys diff --git a/module-sys/Service/Service.hpp b/module-sys/Service/Service.hpp index 55fe9737c..5db4f4c74 100644 --- a/module-sys/Service/Service.hpp +++ b/module-sys/Service/Service.hpp @@ -3,7 +3,6 @@ #pragma once -#include "ServiceForward.hpp" #include "BusProxy.hpp" #include "Common.hpp" // for ReturnCodes, ServicePriority, BusChannels #include "Mailbox.hpp" // for Mailbox @@ -26,6 +25,19 @@ namespace sys { + struct Proxy; + class Timer; + + namespace timer + { + class SystemTimer; + } // namespace timer +} // namespace sys + +namespace sys +{ + using MessageHandler = std::function; + class Service : public cpp_freertos::Thread, public std::enable_shared_from_this { public: diff --git a/module-sys/Service/ServiceForward.hpp b/module-sys/Service/ServiceForward.hpp deleted file mode 100644 index 71eefd7f8..000000000 --- a/module-sys/Service/ServiceForward.hpp +++ /dev/null @@ -1,20 +0,0 @@ -// 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 "MessageForward.hpp" -#include - -namespace sys -{ - using MessageHandler = std::function; - - struct Proxy; - class Timer; - - namespace timer - { - class SystemTimer; - } // namespace timer -} // namespace sys diff --git a/module-sys/Service/ServiceProxy.hpp b/module-sys/Service/ServiceProxy.hpp deleted file mode 100644 index d56733012..000000000 --- a/module-sys/Service/ServiceProxy.hpp +++ /dev/null @@ -1,46 +0,0 @@ -// 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 -#include -#include - -namespace sys -{ - class Service; -} - -namespace service -{ - /// Proxy class for classes using Service raw pointer - /// - initialized in InitHandler - /// - provides weak bounding with Service (to avoid infinite shared ptr loop) - /// - used to provide Class <-> System interface - /// - invalid ServiceProxy will throw runtime error instead of crash on invalid Service* ptr - class ServiceProxy - { - private: - std::weak_ptr service; - - protected: - [[nodiscard]] std::shared_ptr getService() - { - if (auto val = service.lock(); val != nullptr) { - return val; - } - throw std::runtime_error("no service"); - } - - public: - explicit ServiceProxy(std::weak_ptr service) : service(std::move(service)) - {} - ServiceProxy() = default; - virtual ~ServiceProxy() = default; - [[nodiscard]] bool isValid() const noexcept - { - return !service.expired(); - } - }; -} // namespace service diff --git a/module-utils/Split.hpp b/module-utils/Split.hpp deleted file mode 100644 index 975b6d05b..000000000 --- a/module-utils/Split.hpp +++ /dev/null @@ -1,51 +0,0 @@ -// 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 -#include - -namespace utils -{ - template void split(const std::string &s, char delim, Out result) - { - std::stringstream ss(s); - std::string item; - while (std::getline(ss, item, delim)) { - *(result++) = item; - } - } - - static inline std::vector split(const std::string &s, char delim) - { - std::vector elems; - split(s, delim, std::back_inserter(elems)); - return elems; - } - - static inline std::vector split(const std::string &s, - const std::string &delimiter, - const bool skipEmptyTokens = true) - { - size_t pos_start = 0, pos_end, delim_len = delimiter.length(); - std::string token; - std::vector res; - uint32_t tokenCount = 0; - - while (((pos_end = s.find(delimiter, pos_start)) != std::string::npos)) { - token = s.substr(pos_start, pos_end - pos_start); - pos_start = pos_end + delim_len; - if (!skipEmptyTokens || !token.empty()) { - tokenCount++; - res.push_back(token); - } - } - - token = s.substr(pos_start); - if (!skipEmptyTokens || !token.empty()) { - res.push_back(token); - } - return res; - } -} // namespace utils diff --git a/module-utils/Utils.hpp b/module-utils/Utils.hpp index 1cec68ce2..e052c8559 100644 --- a/module-utils/Utils.hpp +++ b/module-utils/Utils.hpp @@ -1,8 +1,7 @@ -// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved. +// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved. // For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md #pragma once -#include "Split.hpp" #include "i18n/i18n.hpp" #include // std::find_if_not #include @@ -30,6 +29,46 @@ namespace utils s << std::setw(sizeof(T) * 2) << std::hex << static_cast(c); return s.str(); } + template void split(const std::string &s, char delim, Out result) + { + std::stringstream ss(s); + std::string item; + while (std::getline(ss, item, delim)) { + *(result++) = item; + } + } + + static inline std::vector split(const std::string &s, char delim) + { + std::vector elems; + split(s, delim, std::back_inserter(elems)); + return elems; + } + + static inline std::vector split(const std::string &s, + const std::string &delimiter, + const bool skipEmptyTokens = true) + { + size_t pos_start = 0, pos_end, delim_len = delimiter.length(); + std::string token; + std::vector res; + uint32_t tokenCount = 0; + + while (((pos_end = s.find(delimiter, pos_start)) != std::string::npos)) { + token = s.substr(pos_start, pos_end - pos_start); + pos_start = pos_end + delim_len; + if (!skipEmptyTokens || !token.empty()) { + tokenCount++; + res.push_back(token); + } + } + + token = s.substr(pos_start); + if (!skipEmptyTokens || !token.empty()) { + res.push_back(token); + } + return res; + } static inline std::string removeNewLines(const std::string &s) { diff --git a/test/mock-freertos-tls.cpp b/test/mock-freertos-tls.cpp index 522e232a0..2677591d5 100644 --- a/test/mock-freertos-tls.cpp +++ b/test/mock-freertos-tls.cpp @@ -1,9 +1,7 @@ -// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved. +// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved. // For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md -typedef long BaseType_t; -typedef void *TaskHandle_t; -#define configNUM_THREAD_LOCAL_STORAGE_POINTERS 5 +#include namespace {