[EGD-6019] Revert of two commits

This reverts commit b6416b15da.
This reverts commit e2f3882d8a.
This commit is contained in:
Przemysław Brudny committed 2021-05-14 09:54:36 +02:00
1 parent db8c1d35e5
commit e71a044bd3
45 files changed
+1162 -766

No files matched your search

-10
View File
@@ -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;
"
#---------
+2 -3
View File
@@ -102,7 +102,7 @@ namespace app
default_window(gui::name::window::main_window), windowsStack(this),
keyTranslator{std::make_unique<gui::KeyInputSimpleTranslation>()}, startInBackground{startInBackground},
callbackStorage{std::make_unique<CallbackStorage>()}, topBarManager{std::make_unique<TopBarManager>()},
settings(std::make_unique<settings::Settings>()), phoneMode{mode}, phoneLockSubject(this)
settings(std::make_unique<settings::Settings>(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) {
@@ -383,6 +383,8 @@ namespace app
sys::ReturnCodes ApplicationDesktop::DeinitHandler()
{
LOG_INFO("DeinitHandler");
settings->unregisterValueChange();
return sys::ReturnCodes::Success;
}
@@ -460,7 +460,7 @@ namespace app
return std::make_unique<gui::CertificationWindow>(app);
});
windowsFactory.attach(gui::window::name::technical_information, [&](Application *app, const std::string &name) {
auto factoryData = std::make_unique<FactoryData>(*settings);
auto factoryData = std::make_unique<FactoryData>(std::make_unique<::settings::Settings>(this));
auto presenter = std::make_unique<TechnicalWindowPresenter>(std::move(factoryData));
return std::make_unique<gui::TechnicalInformationWindow>(app, std::move(presenter));
});
@@ -5,28 +5,28 @@
#include <service-db/Settings.hpp>
#include <service-db/agents/settings/FactorySettings.hpp>
FactoryData::FactoryData(settings::Settings &settings) : settings(settings)
FactoryData::FactoryData(std::unique_ptr<settings::Settings> 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);
}
@@ -20,7 +20,7 @@ class AbstractFactoryData
class FactoryData : public AbstractFactoryData
{
public:
explicit FactoryData(settings::Settings &settings);
explicit FactoryData(std::unique_ptr<settings::Settings> 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::Settings> settings;
};
@@ -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<settings::Settings>()),
autoLockEnabled(false), settings(std::make_unique<settings::Settings>(this)),
phoneModeObserver(std::make_unique<sys::phone_modes::Observer>()),
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;
}
@@ -94,7 +94,7 @@ static constexpr std::initializer_list<std::pair<audio::DbPathElement, const cha
ServiceAudio::ServiceAudio()
: sys::Service(service::name::audio, "", audioServiceStackSize, sys::ServicePriority::Idle),
audioMux([this](auto... params) { return this->AudioServicesCallback(params...); }),
settingsProvider(std::make_unique<settings::Settings>())
settingsProvider(std::make_unique<settings::Settings>(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;
}
@@ -45,6 +45,9 @@ namespace
ServiceBluetooth::ServiceBluetooth() : sys::Service(service::name::bluetooth, "", BluetoothServiceStackDepth)
{
auto settings = std::make_unique<settings::Settings>(this);
settingsHolder = std::make_shared<bluetooth::SettingsHolder>(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::Settings>();
settings->init(service::ServiceProxy(shared_from_this()));
settingsHolder = std::make_shared<bluetooth::SettingsHolder>(std::move(settings));
bluetooth::KeyStorage::settings = settingsHolder;
worker = std::make_unique<BluetoothWorker>(this);
worker->run();
@@ -107,7 +105,6 @@ sys::ReturnCodes ServiceBluetooth::InitHandler()
sys::ReturnCodes ServiceBluetooth::DeinitHandler()
{
settingsHolder->deinit();
worker->deinit();
return sys::ReturnCodes::Success;
}
@@ -53,9 +53,4 @@ namespace bluetooth
}
});
}
void SettingsHolder::deinit()
{
settingsProvider->deinit();
}
} // namespace Bluetooth
@@ -84,7 +84,6 @@ namespace bluetooth
void setValue(const Settings &newSetting, const SettingEntry &value);
std::function<void()> onStateChange;
std::function<void(const std::string &)> onLinkKeyAdded;
void deinit();
private:
static std::map<Settings, std::string> settingString;
@@ -180,6 +180,15 @@ ServiceCellular::ServiceCellular()
bus.channels.push_back(sys::BusChannel::ServiceEvtmgrNotifications);
bus.channels.push_back(sys::BusChannel::PhoneModeChanges);
settings = std::make_unique<settings::Settings>(this);
connectionManager = std::make_unique<ConnectionManager>(
utils::getNumericValue<bool>(
settings->getValue(settings::Cellular::offlineMode, settings::SettingsScope::Global)),
static_cast<std::chrono::minutes>(utils::getNumericValue<int>(settings->getValue(
settings->getValue(settings::Offline::connectionFrequency, settings::SettingsScope::Global)))),
std::make_shared<ConnectionManagerCellularCommands>(*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::Settings>();
settings->init(service::ServiceProxy(shared_from_this()));
connectionManager = std::make_unique<ConnectionManager>(
utils::getNumericValue<bool>(
settings->getValue(settings::Cellular::offlineMode, settings::SettingsScope::Global)),
static_cast<std::chrono::minutes>(utils::getNumericValue<int>(settings->getValue(
settings->getValue(settings::Offline::connectionFrequency, settings::SettingsScope::Global)))),
std::make_shared<ConnectionManagerCellularCommands>(*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;
}
@@ -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
+1 -19
View File
@@ -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 <Split.hpp>
#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
@@ -2,15 +2,18 @@
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#include <service-db/Settings.hpp>
#include <service-db/SettingsMessages.hpp>
#include <service-db/SettingsCache.hpp>
#include <memory>
#include <stdexcept>
#include <Service/Common.hpp>
#include <Service/Message.hpp>
#include <Service/Service.hpp>
#include <log/log.hpp>
#include <utility>
#include <vector>
#if defined(DEBUG_SETTINGS_DB) and DEBUG_SETTINGS_DB == 1
#include <log/log.hpp>
#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<sys::Service>(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<settings::Messages::SettingsMessage> &&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<settings::Messages::VariableChanged *>(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<sys::ResponseMessage>();
}
auto Settings::handleCurrentProfileChanged(sys::Message *req) -> sys::MessagePointer
{
log_debug("handleCurrentProfileChanged");
if (auto msg = dynamic_cast<settings::Messages::CurrentProfileChanged *>(req)) {
auto profile = msg->getProfileName();
log_debug("handleCurrentProfileChanged: %s", profile.c_str());
cbProfile(profile);
}
return std::make_shared<sys::ResponseMessage>();
}
auto Settings::handleCurrentModeChanged(sys::Message *req) -> sys::MessagePointer
{
log_debug("handleCurrentModeChanged");
if (auto msg = dynamic_cast<settings::Messages::CurrentModeChanged *>(req)) {
auto mode = msg->getProfileName();
log_debug("handleCurrentModeChanged: %s", mode.c_str());
cbMode(mode);
}
return std::make_shared<sys::ResponseMessage>();
}
auto Settings::handleProfileListResponse(sys::Message *req) -> sys::MessagePointer
{
log_debug("handleProfileListResponse");
if (auto msg = dynamic_cast<settings::Messages::ProfileListResponse *>(req)) {
auto profiles = msg->getValue();
log_debug("handleProfileListResponse: %zu elements", profiles.size());
cbAllProfiles(profiles);
}
return std::make_shared<sys::ResponseMessage>();
}
auto Settings::handleModeListResponse(sys::Message *req) -> sys::MessagePointer
{
log_debug("handleModeListResponse");
if (auto msg = dynamic_cast<settings::Messages::ModeListResponse *>(req)) {
auto modes = msg->getValue();
log_debug("handleModeListResponse: %zu elements", modes.size());
cbAllModes(modes);
}
return std::make_shared<sys::ResponseMessage>();
}
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<settings::Messages::RegisterOnVariableChange>(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<settings::Messages::RegisterOnVariableChange>(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<settings::Messages::UnregisterOnVariableChange>(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<settings::Messages::UnregisterOnVariableChange>(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<settings::Messages::SetVariable>(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<settings::Messages::ListProfiles>());
}
cbAllProfiles = std::move(cb);
}
void Settings::setCurrentProfile(const std::string &profile)
{
sendMsg(std::make_shared<settings::Messages::SetCurrentProfile>(profile));
}
void Settings::addProfile(const std::string &profile)
{
sendMsg(std::make_shared<settings::Messages::AddProfile>(profile));
}
void Settings::registerProfileChange(ProfileChangedCallback cb)
{
if (nullptr != cbProfile) {
log_debug("Profile change callback already exists, overwritting");
}
else {
sendMsg(std::make_shared<settings::Messages::RegisterOnProfileChange>());
}
cbProfile = std::move(cb);
}
void Settings::unregisterProfileChange()
{
cbProfile = nullptr;
sendMsg(std::make_shared<settings::Messages::UnregisterOnProfileChange>());
}
void Settings::getAllModes(OnAllModesRetrievedCallback cb)
{
if (nullptr == cbAllModes) {
sendMsg(std::make_shared<settings::Messages::ListModes>());
}
cbAllModes = std::move(cb);
}
void Settings::setCurrentMode(const std::string &mode)
{
sendMsg(std::make_shared<settings::Messages::SetCurrentMode>(mode));
}
void Settings::addMode(const std::string &mode)
{
sendMsg(std::make_shared<settings::Messages::AddMode>(mode));
}
void Settings::registerModeChange(ModeChangedCallback cb)
{
if (nullptr != cbMode) {
log_debug("ModeChange callback allready set overwriting");
}
else {
sendMsg(std::make_shared<settings::Messages::RegisterOnModeChange>());
}
cbMode = std::move(cb);
}
void Settings::unregisterModeChange()
{
cbMode = nullptr;
sendMsg(std::make_shared<settings::Messages::UnregisterOnModeChange>());
}
} // namespace settings
@@ -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<std::string>
{
auto qProfiles = database->query(settings::Statements::getDictValue, settings::DbPaths::phone_profile);
if (nullptr == qProfiles || 0 == qProfiles->getRowCount()) {
return std::list<std::string>{};
}
std::list<std::string> 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<std::string>
{
auto qModes = database->query(settings::Statements::getDictValue, settings::DbPaths::phone_mode);
if (nullptr == qModes || 0 == qModes->getRowCount()) {
return std::list<std::string>{};
}
std::list<std::string> 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<settings::Messages::GetVariable *>(req)) {
@@ -180,3 +292,146 @@ auto SettingsAgent::handleUnregisterOnVariableChange(sys::Message *req) -> sys::
}
return std::make_shared<sys::ResponseMessage>();
}
// profile
auto SettingsAgent::handleRegisterProfileChange(sys::Message *req) -> sys::MessagePointer
{
if (auto msg = dynamic_cast<settings::Messages::RegisterOnProfileChange *>(req)) {
if (dbRegisterOnProfileChange(msg->sender)) {
profileChangedRecipients.insert(msg->sender);
auto msgCurrentProfile = std::make_shared<settings::Messages::CurrentProfileChanged>(dbGetCurrentProfile());
parentService->bus.sendUnicast(std::move(msgCurrentProfile), msg->sender);
}
}
return std::make_shared<sys::ResponseMessage>();
}
auto SettingsAgent::handleUnregisterProfileChange(sys::Message *req) -> sys::MessagePointer
{
if (auto msg = dynamic_cast<settings::Messages::UnregisterOnProfileChange *>(req)) {
if (dbUnregisterOnProfileChange(msg->sender)) {
profileChangedRecipients.erase(msg->sender);
}
}
return std::make_shared<sys::ResponseMessage>();
}
auto SettingsAgent::handleSetCurrentProfile(sys::Message *req) -> sys::MessagePointer
{
if (auto msg = dynamic_cast<settings::Messages::SetCurrentProfile *>(req)) {
auto profile = msg->getProfileName();
if (dbSetCurrentProfile(profile)) {
for (const auto &service : profileChangedRecipients) {
if (service != msg->sender) {
auto msgProfileChanged = std::make_shared<settings::Messages::CurrentProfileChanged>(profile);
parentService->bus.sendUnicast(std::move(msgProfileChanged), service);
}
}
}
}
return std::make_shared<sys::ResponseMessage>();
}
auto SettingsAgent::handleGetCurrentProfile(sys::Message *req) -> sys::MessagePointer
{
if (nullptr != dynamic_cast<settings::Messages::GetCurrentProfile *>(req)) {
auto service = profileChangedRecipients.find(req->sender);
if (profileChangedRecipients.end() != service) {
auto msgCurrentProfile = std::make_shared<settings::Messages::CurrentProfileChanged>(dbGetCurrentProfile());
parentService->bus.sendUnicast(std::move(msgCurrentProfile), *service);
}
}
return std::make_shared<sys::ResponseMessage>();
}
auto SettingsAgent::handleAddProfile(sys::Message *req) -> sys::MessagePointer
{
if (auto msg = dynamic_cast<settings::Messages::AddProfile *>(req)) {
if (dbAddProfile(msg->getProfileName())) {
auto allProfiles = dbGetAllProfiles();
for (const auto &service : profileChangedRecipients) {
if (service != req->sender) {
auto msgAllProfiles = std::make_shared<settings::Messages::ProfileListResponse>(allProfiles);
parentService->bus.sendUnicast(std::move(msgAllProfiles), service);
}
}
}
}
return std::make_shared<sys::ResponseMessage>();
}
auto SettingsAgent::handleListProfiles(sys::Message *req) -> sys::MessagePointer
{
if (nullptr != dynamic_cast<settings::Messages::ListProfiles *>(req)) {
profileChangedRecipients.insert(req->sender);
auto msgAllProfiles = std::make_shared<settings::Messages::ProfileListResponse>(dbGetAllProfiles());
parentService->bus.sendUnicast(std::move(msgAllProfiles), req->sender);
}
return std::make_shared<sys::ResponseMessage>();
}
// mode
auto SettingsAgent::handleRegisterOnModeChange(sys::Message *req) -> sys::MessagePointer
{
if (auto msg = dynamic_cast<settings::Messages::RegisterOnModeChange *>(req)) {
if (dbRegisterOnModeChange(msg->sender)) {
modeChangeRecipients.insert(msg->sender);
auto msgMode = std::make_shared<settings::Messages::CurrentModeChanged>(dbGetCurrentMode());
parentService->bus.sendUnicast(std::move(msgMode), msg->sender);
}
}
return std::make_shared<sys::ResponseMessage>();
}
auto SettingsAgent::handleUnregisterOnModeChange(sys::Message *req) -> sys::MessagePointer
{
if (nullptr != dynamic_cast<settings::Messages::UnregisterOnModeChange *>(req)) {
dbUnregisterOnModeChange(req->sender);
modeChangeRecipients.erase(req->sender);
}
return std::make_shared<sys::ResponseMessage>();
}
auto SettingsAgent::handleSetCurrentMode(sys::Message *req) -> sys::MessagePointer
{
if (auto msg = dynamic_cast<settings::Messages::SetCurrentMode *>(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<settings::Messages::CurrentModeChanged>(newMode);
parentService->bus.sendUnicast(std::move(msgModeChanged), service);
}
}
}
}
}
return std::make_shared<sys::ResponseMessage>();
}
auto SettingsAgent::handleGetCurrentMode(sys::Message *req) -> sys::MessagePointer
{
if (nullptr != dynamic_cast<settings::Messages::GetCurrentMode *>(req)) {
if (modeChangeRecipients.end() != modeChangeRecipients.find(req->sender)) {
auto msgMode = std::make_shared<settings::Messages::CurrentModeChanged>(dbGetCurrentMode());
parentService->bus.sendUnicast(std::move(msgMode), req->sender);
}
}
return std::make_shared<sys::ResponseMessage>();
}
auto SettingsAgent::handleAddMode(sys::Message *req) -> sys::MessagePointer
{
if (auto msg = dynamic_cast<settings::Messages::AddMode *>(req)) {
if (dbAddMode(msg->getProfileName())) {
auto allModes = dbGetAllModes();
for (const auto &service : modeChangeRecipients) {
if (service != msg->sender) {
auto msgAllModes = std::make_shared<settings::Messages::ModeListResponse>(allModes);
parentService->bus.sendUnicast(std::move(msgAllModes), service);
}
}
}
}
return std::make_shared<sys::ResponseMessage>();
}
auto SettingsAgent::handleListModes(sys::Message *req) -> sys::MessagePointer
{
if (nullptr != dynamic_cast<settings::Messages::ListModes *>(req)) {
modeChangeRecipients.insert(req->sender);
auto msgAllModes = std::make_shared<settings::Messages::ModeListResponse>(dbGetAllModes());
parentService->bus.sendUnicast(std::move(msgAllModes), req->sender);
}
return std::make_shared<sys::ResponseMessage>();
}
@@ -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<std::string>;
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<std::string>;
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;
};
@@ -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 <service-db/SettingsCache.hpp>
#include <mutex.hpp>
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<EntryPath, std::string> 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
@@ -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 <service-db/EntryPath.hpp>
#include <service-db/SettingsMessages.hpp>
#include <service-db/Settings.hpp>
#include <service-db/SettingsCache.hpp>
#include <service-db/DBServiceName.hpp>
#include <Service/ServiceProxy.hpp>
#include <Service/Service.hpp>
#include <utility>
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<void(EntryPath, std::string)> 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<settings::Messages::VariableChanged *>(req)) {
onChange(msg->getPath(), msg->getValue().value_or(""));
}
return std::make_shared<sys::ResponseMessage>();
});
}
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 <typename T, typename... Args> auto message(sys::BusProxy &bus, Args... args)
{
bus.sendUnicast(std::make_shared<T>(args...), service::name::db);
}
void SettingsProxy::registerValueChange(EntryPath path)
{
message<settings::Messages::RegisterOnVariableChange>(getService()->bus, std::move(path));
}
void SettingsProxy::unregisterValueChange(EntryPath path)
{
message<settings::Messages::UnregisterOnVariableChange>(getService()->bus, std::move(path));
}
void SettingsProxy::setValue(const EntryPath &path, const std::string &value)
{
message<settings::Messages::SetVariable>(getService()->bus, path, value);
}
} // namespace settings
@@ -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 <service-db/SettingsScope.hpp>
#include <string>
#include <type_traits>
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
@@ -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 <module-sys/Service/Message.hpp>
#include <service-db/DBServiceName.hpp>
#include "SettingsScope.hpp"
#include "SettingsProxy.hpp"
#include "SettingsMessages.hpp"
#include <cstdint>
#include <functional>
@@ -14,23 +15,23 @@
#include <memory>
#include <optional>
#include <string>
#include <exception>
namespace settings
{
class SettingsCache;
class Settings
{
public:
using ValueChangedCallback = std::function<void(const std::string &)>;
using ValueChangedCallbackWithName = std::function<void(const std::string &, const std::string &value)>;
using ProfileChangedCallback = std::function<void(const std::string &)>;
using ModeChangedCallback = ProfileChangedCallback;
using ListOfProfiles = std::list<std::string>;
using ListOfModes = ListOfProfiles;
using OnAllProfilesRetrievedCallback = std::function<void(const ListOfProfiles &)>;
using OnAllModesRetrievedCallback = std::function<void(const ListOfModes &)>;
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<sys::Service> app;
std::string serviceName;
std::string phoneMode;
std::string profile;
SettingsCache *cache;
using ValueCb = std::map<EntryPath, std::pair<ValueChangedCallback, ValueChangedCallbackWithName>>;
ValueCb cbValues;
void handleVariableChanged(const EntryPath &path, const std::string &value);
ModeChangedCallback cbMode;
OnAllModesRetrievedCallback cbAllModes;
ProfileChangedCallback cbProfile;
OnAllProfilesRetrievedCallback cbAllProfiles;
void sendMsg(std::shared_ptr<settings::Messages::SettingsMessage> &&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
@@ -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 <mutex.hpp>
#include "SettingsMessages.hpp"
#include <map>
@@ -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<EntryPath, std::string> settingsMap;
mutable cpp_freertos::MutexStandard settingsMutex;
};
} // namespace settings
@@ -5,16 +5,49 @@
#include <MessageType.hpp>
#include <Service/Message.hpp>
#include "EntryPath.hpp"
#include <service-db/SettingsScope.hpp>
#include <list>
#include <memory>
#include <set>
#include <utility>
#include <variant>
#include <module-utils/Utils.hpp>
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<std::string> value = {})
: path(std::move(path)), value(std::move(value))
: SettingsMessage(), path(std::move(path)), value(std::move(value))
{}
[[nodiscard]] auto getValue() const -> std::optional<std::string>
@@ -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<std::string>
{
return profiles;
}
private:
std::set<std::string> 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<std::string>
{
return modes;
}
private:
std::set<std::string> 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<std::string> 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<std::string> value) : SettingsMessage(), value(std::move(value))
{}
[[nodiscard]] auto getValue() const -> std::list<std::string>
{
return value;
}
protected:
std::list<std::string> value;
};
class ProfileListResponse : public ListResponse
{
public:
ProfileListResponse() = default;
explicit ProfileListResponse(std::list<std::string> profiles) : ListResponse(profiles)
{}
};
class ModeListResponse : public ListResponse
{
public:
ModeListResponse() = default;
explicit ModeListResponse(std::list<std::string> modes) : ListResponse(modes)
{}
};
} // namespace Messages
} // namespace settings
@@ -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 <functional>
namespace settings
{
class SettingsProxy : private service::ServiceProxy
{
public:
SettingsProxy() = default;
~SettingsProxy();
explicit SettingsProxy(const service::ServiceProxy &interface);
void init(std::function<void(EntryPath, std::string)> 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<void(EntryPath, std::string)> onChangeHandler;
};
} // namespace settings
@@ -32,4 +32,3 @@ add_catch2_executable(
)
add_subdirectory(test-settings)
add_subdirectory(test-settings-Settings)
@@ -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 <catch2/catch.hpp> // for Section, SourceLineInfo, SECTION, SectionInfo, StringRef, TEST_CASE
@@ -83,6 +83,24 @@ namespace settings
}
return std::make_shared<sys::ResponseMessage>();
};
sys::MessagePointer handleListProfiles(sys::Message *req)
{
if (dynamic_cast<settings::Messages::ListProfiles *>(req) != nullptr) {
std::list<std::string> profiles = {"silent", "loud"};
return std::make_shared<settings::Messages::ProfileListResponse>(profiles);
}
return std::make_shared<sys::ResponseMessage>();
};
sys::MessagePointer handleListModes(sys::Message *req)
{
if (dynamic_cast<settings::Messages::ListProfiles *>(req) != nullptr) {
std::list<std::string> modes = {"mode1", "mode2"};
return std::make_shared<settings::Messages::ModeListResponse>(modes);
}
return std::make_shared<sys::ResponseMessage>();
};
};
} // 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::Messages::ListProfiles>(), "settings");
settings.bus.sendUnicast(std::make_shared<settings::Messages::AddProfile>("new-profile"), "settings");
settings.bus.sendUnicast(std::make_shared<settings::Messages::GetCurrentProfile>(), "settings");
settings.bus.sendUnicast(std::make_shared<settings::Messages::CurrentProfileChanged>("profile"), "settings");
}
SECTION("Send mode messages")
{
settings::Service settings("settings");
settings.InitHandler();
settings.bus.sendUnicast(std::make_shared<settings::Messages::ListModes>(), "settings");
settings.bus.sendUnicast(std::make_shared<settings::Messages::GetCurrentMode>(), "settings");
settings.bus.sendUnicast(std::make_shared<settings::Messages::AddMode>("new-mode"), "settings");
settings.bus.sendUnicast(std::make_shared<settings::Messages::CurrentModeChanged>("mode"), "settings");
}
}
@@ -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
)
@@ -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 <catch2/catch.hpp>
@@ -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 <catch2/catch.hpp>
#include <memory>
#include <module-sys/Service/ServiceProxy.hpp>
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<sys::Service> 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<sys::Service>();
auto interface = Interface_imp(service);
REQUIRE(interface.isValid());
REQUIRE_NOTHROW(interface.getService());
}
TEST_CASE("Interface - expired")
{
Interface_imp *interface;
std::shared_ptr<sys::Service> expired;
{
auto service = std::make_shared<sys::Service>();
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<sys::Service>();
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());
}
@@ -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 <catch2/catch.hpp>
#include <module-services/service-db/service-db/Settings.hpp>
#include "module-services/service-db/service-db/SettingsCache.hpp"
#include <utility>
/// stub
namespace settings
{
SettingsProxy::~SettingsProxy()
{}
SettingsProxy::SettingsProxy(const service::ServiceProxy &interface) : service::ServiceProxy(interface)
{}
void SettingsProxy::init(std::function<void(EntryPath, std::string)> 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")
{}
}
@@ -11,5 +11,7 @@ add_catch2_executable(
module-audio
service-cellular
module-cellular
iosyscalls
DEPS
disk_image
)
@@ -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 <catch2/catch.hpp>
@@ -27,60 +27,105 @@ TEST_CASE("SettingsApi")
std::shared_ptr<settings::MyService> varWritter;
std::shared_ptr<settings::MyService> varReader;
std::shared_ptr<settings::AppTest> testVar;
std::shared_ptr<settings::ServiceProfile> profWritter;
std::shared_ptr<settings::ServiceProfile> profReader;
std::shared_ptr<settings::AppTestProfileMode> testProf;
std::shared_ptr<settings::ServiceMode> modeWritter;
std::shared_ptr<settings::ServiceMode> modeReader;
std::shared_ptr<settings::AppTestProfileMode> testMode;
std::shared_ptr<std::mutex> testStart;
std::shared_ptr<settings::Settings> postMortemSetting;
manager->StartSystem(
nullptr,
[manager,
&varWritter,
&varReader,
&testVar,
&profWritter,
&profReader,
&testProf,
&modeWritter,
&modeReader,
&testMode,
&testStart]() {
// preliminary
testStart = std::make_shared<std::mutex>();
testStart->lock();
std::cout << "start thr_id: " << std::this_thread::get_id() << std::endl << std::flush;
auto ret = sys::SystemManager::RunSystemService(
std::make_shared<EventManager>(service::name::evt_manager), manager.get());
ret &= sys::SystemManager::RunSystemService(std::make_shared<ServiceDB>(), manager.get());
manager->StartSystem(nullptr, [manager, &varWritter, &varReader, &testVar, &testStart, &postMortemSetting]() {
// preliminary
testStart = std::make_shared<std::mutex>();
testStart->lock();
std::cout << "start thr_id: " << std::this_thread::get_id() << std::endl << std::flush;
auto ret = sys::SystemManager::RunSystemService(std::make_shared<EventManager>(service::name::evt_manager),
manager.get());
ret &= sys::SystemManager::RunSystemService(std::make_shared<ServiceDB>(), manager.get());
varWritter = std::make_shared<settings::MyService>("writterVar");
varReader = std::make_shared<settings::MyService>("readerVar");
varWritter = std::make_shared<settings::MyService>("writterVar");
varReader = std::make_shared<settings::MyService>("readerVar");
ret &= sys::SystemManager::RunSystemService(varWritter, manager.get());
ret &= sys::SystemManager::RunSystemService(varReader, manager.get());
postMortemSetting = varWritter->getSettings();
testVar = std::make_shared<settings::AppTest>("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<settings::ServiceProfile>("writterProf");
profReader = std::make_shared<settings::ServiceProfile>("readerProf");
testVar = std::make_shared<settings::AppTest>("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<settings::UTMsg::UTMsgStart>();
manager->bus.sendUnicast(std::move(msgStart), "appTest");
testProf = std::make_shared<settings::AppTestProfileMode>(
"appTestProfile", profWritter, profReader, testStart);
ret &= sys::SystemManager::RunSystemService(testProf, manager.get());
msgStart = std::make_shared<settings::UTMsg::UTMsgStart>();
manager->bus.sendUnicast(std::move(msgStart), "appTestProfile");
modeWritter = std::make_shared<settings::ServiceMode>("writterMode");
modeReader = std::make_shared<settings::ServiceMode>("readerMode");
msgStart = std::make_shared<settings::UTMsg::UTMsgStart>();
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<settings::AppTestProfileMode>("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<settings::UTMsg::UTMsgStart>();
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<settings::UTMsg::UTMsgStart>();
manager->bus.sendUnicast(std::move(msgStart), "appTestProfile");
msgStart = std::make_shared<settings::UTMsg::UTMsgStart>();
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");
}
}
@@ -66,21 +66,6 @@ namespace settings
std::string last_v;
std::vector<std::string> 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<MyService> setter,
std::shared_ptr<MyService> 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<settings::UTMsg::UTMsgStart *>(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<settings::UTMsg::ReqRegValChg>("brightness", "none");
bus.sendUnicast(std::move(msg), getter->GetName());
}
}
else if (nullptr != dynamic_cast<settings::UTMsg::CnfRegValChg *>(msg)) {
if (isState(State::Start)) {
setState(State::Register);
if (state == State::Start) {
state = State::Register;
}
}
else if (auto m = dynamic_cast<settings::UTMsg::CnfValChg *>(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<settings::UTMsg::ReqSetVal>("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<settings::UTMsg::ReqUnRegValChg>("brightness", "empty");
bus.sendUnicast(std::move(msg), getter->GetName());
setState(State::UnregisterWait);
state = State::UnregisterWait;
}
}
}
else if (nullptr != dynamic_cast<settings::UTMsg::CnfUnRegValChg *>(msg)) {
if (isState(State::UnregisterWait)) {
setState(State::Unregister);
if (state == State::UnregisterWait) {
state = State::Unregister;
auto msg = std::make_shared<settings::UTMsg::ReqSetVal>("brightness", v.back() + "2");
bus.sendUnicast(std::move(msg), setter->GetName());
}
}
else if (auto m = dynamic_cast<settings::UTMsg::CnfReqSetVal *>(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<settings::UTMsg::UTMsgStop>();
@@ -152,7 +137,7 @@ namespace settings
}
}
else if (nullptr != dynamic_cast<settings::UTMsg::UTMsgStop *>(msg)) {
if (isState(State::Unregister)) {
if (state == State::Unregister) {
closeSystem();
}
}
@@ -183,69 +168,69 @@ namespace settings
if (nullptr != dynamic_cast<settings::UTMsg::UTMsgStart *>(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<settings::UTMsg::ReqRegProfileChg>();
bus.sendUnicast(std::move(msg), getter->GetName());
}
}
else if (nullptr != dynamic_cast<settings::UTMsg::CnfRegProfileChg *>(msg)) {
if (isState(State::Start)) {
setState(State::Register);
if (state == State::Start) {
state = State::Register;
}
}
else if (auto m = dynamic_cast<settings::UTMsg::ProfileChg *>(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<settings::UTMsg::ReqSetCurrentProfile>(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<settings::UTMsg::ReqUnRegProfileChg>();
bus.sendUnicast(std::move(msg), getter->GetName());
setState(State::UnregisterWait);
state = State::UnregisterWait;
}
}
}
else if (nullptr != dynamic_cast<settings::UTMsg::CnfUnRegProfileChg *>(msg)) {
if (isState(State::UnregisterWait)) {
setState(State::Unregister);
if (state == State::UnregisterWait) {
state = State::Unregister;
auto msg = std::make_shared<settings::UTMsg::ReqSetCurrentProfile>(v.back() + "2");
bus.sendUnicast(std::move(msg), setter->GetName());
}
}
else if (auto m = dynamic_cast<settings::UTMsg::CnfSetCurrentProfile *>(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<settings::UTMsg::ReqGetAllProfiles>();
bus.sendUnicast(std::move(msg), getter->GetName());
}
}
else if (nullptr != dynamic_cast<settings::UTMsg::CnfGetAllProfiles *>(msg)) {
if (isState(State::Unregister)) {
setState(State::RegisterAllWait);
if (state == State::Unregister) {
state = State::RegisterAllWait;
}
}
else if (auto m = dynamic_cast<settings::UTMsg::ProfilesChg *>(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<settings::UTMsg::ReqAddProfile>("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<settings::UTMsg::CnfAddProfile *>(msg)) {
if (isState(State::RegisterAll)) {
setState(State::RegisterAllAddWait);
if (state == State::RegisterAll) {
state = State::RegisterAllAddWait;
}
}
else if (nullptr != dynamic_cast<settings::UTMsg::UTMsgStop *>(msg)) {
if (isState(State::RegisterAllAdd)) {
if (state == State::RegisterAllAdd) {
closeSystem();
}
}
@@ -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 <memory>
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<settings::Settings>(this);
}
std::shared_ptr<settings::Settings> mySettings;
std::vector<std::string> 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<settings::Settings>();
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<settings::Settings> 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<settings::UTMsg::ReqRegProfileChg *>(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<settings::UTMsg::ProfileChg>(profile);
bus.sendUnicast(std::move(cnf), whoRequestedNotifyOnChange);
}));
auto cnf = std::make_shared<settings::UTMsg::CnfRegProfileChg>();
bus.sendUnicast(std::move(cnf), whoRequestedNotifyOnChange);
}
else if (auto msg = dynamic_cast<settings::UTMsg::ReqUnRegProfileChg *>(req)) {
// unregister
debug("ReqUnRegProfileChg", msg->name, msg->value);
mySettings->unregisterProfileChange();
auto cnf = std::make_shared<settings::UTMsg::CnfUnRegProfileChg>();
bus.sendUnicast(std::move(cnf), msg->sender);
}
else if (auto msg = dynamic_cast<settings::UTMsg::ReqSetCurrentProfile *>(req)) {
// set value
debug("ReqSetCurrentProfile", msg->name, msg->value);
mySettings->setCurrentProfile(msg->name);
auto cnf = std::make_shared<settings::UTMsg::CnfSetCurrentProfile>(msg->name);
bus.sendUnicast(std::move(cnf), msg->sender);
}
else if (auto msg = dynamic_cast<settings::UTMsg::ReqGetAllProfiles *>(req)) {
debug("ReqGetAllProfiles", msg->name, msg->value);
mySettings->getAllProfiles(([this](const settings::Settings::ListOfProfiles &profiles) {
this->profiles = profiles;
auto cnf = std::make_shared<settings::UTMsg::ProfilesChg>(profiles);
bus.sendUnicast(std::move(cnf), whoRequestedNotifyOnChange);
}));
auto cnf = std::make_shared<settings::UTMsg::CnfGetAllProfiles>();
bus.sendUnicast(std::move(cnf), msg->sender);
}
else if (auto msg = dynamic_cast<settings::UTMsg::ReqAddProfile *>(req)) {
debug("ReqAddProfile", msg->name, msg->value);
mySettings->addProfile(msg->name);
auto cnf = std::make_shared<settings::UTMsg::CnfAddProfile>(msg->name);
bus.sendUnicast(std::move(cnf), msg->sender);
}
return std::make_shared<sys::ResponseMessage>();
}
};
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<settings::UTMsg::ReqRegProfileChg *>(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<settings::UTMsg::ProfileChg>(mode);
bus.sendUnicast(std::move(cnf), whoRequestedNotifyOnChange);
}));
auto cnf = std::make_shared<settings::UTMsg::CnfRegProfileChg>();
bus.sendUnicast(std::move(cnf), whoRequestedNotifyOnChange);
}
else if (auto msg = dynamic_cast<settings::UTMsg::ReqUnRegProfileChg *>(req)) {
// unregister
debug("ReqUnRegProfileChg", msg->name, msg->value);
mySettings->unregisterModeChange();
auto cnf = std::make_shared<settings::UTMsg::CnfUnRegProfileChg>();
bus.sendUnicast(std::move(cnf), msg->sender);
}
else if (auto msg = dynamic_cast<settings::UTMsg::ReqSetCurrentProfile *>(req)) {
// set value
debug("ReqSetCurrentProfile", msg->name, msg->value);
mySettings->setCurrentMode(msg->name);
auto cnf = std::make_shared<settings::UTMsg::CnfSetCurrentProfile>(msg->name);
bus.sendUnicast(std::move(cnf), msg->sender);
}
else if (auto msg = dynamic_cast<settings::UTMsg::ReqGetAllProfiles *>(req)) {
debug("ReqGetAllProfiles", msg->name, msg->value);
mySettings->getAllModes(([this](const settings::Settings::ListOfModes &modes) {
this->modes = modes;
auto cnf = std::make_shared<settings::UTMsg::ProfilesChg>(modes);
bus.sendUnicast(std::move(cnf), whoRequestedNotifyOnChange);
}));
auto cnf = std::make_shared<settings::UTMsg::CnfGetAllProfiles>();
bus.sendUnicast(std::move(cnf), msg->sender);
}
else if (auto msg = dynamic_cast<settings::UTMsg::ReqAddProfile *>(req)) {
debug("ReqAddProfile", msg->name, msg->value);
mySettings->addMode(msg->name);
auto cnf = std::make_shared<settings::UTMsg::CnfAddProfile>(msg->name);
bus.sendUnicast(std::move(cnf), msg->sender);
}
return std::make_shared<sys::ResponseMessage>();
}
};
} // namespace settings
@@ -68,6 +68,8 @@ ServiceDesktop::ServiceDesktop()
bus.channels.push_back(sys::BusChannel::PhoneLockChanges);
updateOS = std::make_unique<UpdateMuditaOS>(this);
settings = std::make_unique<settings::Settings>(this);
usbSecurityModel = std::make_unique<sdesktop::USBSecurityModel>(this, settings.get());
}
ServiceDesktop::~ServiceDesktop()
@@ -77,10 +79,6 @@ ServiceDesktop::~ServiceDesktop()
sys::ReturnCodes ServiceDesktop::InitHandler()
{
settings = std::make_unique<settings::Settings>();
settings->init(service::ServiceProxy(shared_from_this()));
usbSecurityModel = std::make_unique<sdesktop::USBSecurityModel>(this, settings.get());
desktopWorker = std::make_unique<WorkerDesktop>(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;
}
@@ -2,7 +2,6 @@
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#include "DeveloperModeHelper.hpp"
#include "service-db/SettingsMessages.hpp"
#include <service-desktop/DesktopMessages.hpp>
#include <parser/ParserUtils.hpp>
@@ -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<settings::Settings>(this)), loggerTimer{sys::TimerFactory::createPeriodicTimer(
this,
loggerTimerName,
std::chrono::milliseconds{loggerDelayMs},
[this](sys::Timer & /*timer*/) { dumpLogsToFile(); })},
screenLightControl(std::make_unique<screen_light_control::ScreenLightControl>(settings, this)),
Vibra(std::make_unique<vibra_handle::Vibra>(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<screen_light_control::ScreenLightControl>(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;
@@ -38,7 +38,7 @@ class EventManager : public sys::Service
void toggleTorchOnOff();
void toggleTorchColor();
std::shared_ptr<settings::Settings> settings = std::make_shared<settings::Settings>();
std::shared_ptr<settings::Settings> settings;
sys::TimerHandle loggerTimer;
sys::TimerHandle keypadLightTimer;
bsp::keypad_backlight::State keypadLightState{bsp::keypad_backlight::State::off};
+1
View File
@@ -3,6 +3,7 @@
#pragma once
#include "FreeRTOSConfig.h"
#include "SystemReturnCodes.hpp"
namespace sys
+13 -1
View File
@@ -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<MessagePointer(Message *)>;
class Service : public cpp_freertos::Thread, public std::enable_shared_from_this<Service>
{
public:
-20
View File
@@ -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 <functional>
namespace sys
{
using MessageHandler = std::function<MessagePointer(Message *)>;
struct Proxy;
class Timer;
namespace timer
{
class SystemTimer;
} // namespace timer
} // namespace sys
-46
View File
@@ -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 <memory>
#include <stdexcept>
#include <utility>
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<sys::Service> service;
protected:
[[nodiscard]] std::shared_ptr<sys::Service> getService()
{
if (auto val = service.lock(); val != nullptr) {
return val;
}
throw std::runtime_error("no service");
}
public:
explicit ServiceProxy(std::weak_ptr<sys::Service> service) : service(std::move(service))
{}
ServiceProxy() = default;
virtual ~ServiceProxy() = default;
[[nodiscard]] bool isValid() const noexcept
{
return !service.expired();
}
};
} // namespace service
-51
View File
@@ -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 <vector>
#include <sstream>
namespace utils
{
template <typename Out> 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<std::string> split(const std::string &s, char delim)
{
std::vector<std::string> elems;
split(s, delim, std::back_inserter(elems));
return elems;
}
static inline std::vector<std::string> 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<std::string> 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
+41 -2
View File
@@ -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 <algorithm> // std::find_if_not
#include <sstream>
@@ -30,6 +29,46 @@ namespace utils
s << std::setw(sizeof(T) * 2) << std::hex << static_cast<unsigned long long>(c);
return s.str();
}
template <typename Out> 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<std::string> split(const std::string &s, char delim)
{
std::vector<std::string> elems;
split(s, delim, std::back_inserter(elems));
return elems;
}
static inline std::vector<std::string> 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<std::string> 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)
{
+2 -4
View File
@@ -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 <thread.hpp>
namespace
{