From b9661350f8dd5180b5f8fe7c758e5ae16452f7cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Ta=C5=84ski?= Date: Fri, 12 Feb 2021 13:01:01 +0100 Subject: [PATCH] [EGD-5697] Framework for phone modes introduced It allows to transmit phone modes information to listening services. --- .../model/ApplicationManager.cpp | 10 ++- .../model/ApplicationManager.hpp | 2 + .../service-evtmgr/EventManager.cpp | 14 +++- module-sys/CMakeLists.txt | 2 + module-sys/PhoneModes/Common.hpp | 49 +++++++++++++ module-sys/PhoneModes/Observer.cpp | 70 +++++++++++++++++++ module-sys/PhoneModes/Observer.hpp | 43 ++++++++++++ module-sys/PhoneModes/Subject.cpp | 61 ++++++++++++++++ module-sys/PhoneModes/Subject.hpp | 33 +++++++++ module-sys/Service/Common.hpp | 5 +- module-sys/SystemManager/SystemManager.cpp | 31 ++++++++ module-sys/SystemManager/SystemManager.hpp | 12 ++++ .../messages/PhoneModeRequest.hpp | 25 +++++++ 13 files changed, 352 insertions(+), 5 deletions(-) create mode 100644 module-sys/PhoneModes/Common.hpp create mode 100644 module-sys/PhoneModes/Observer.cpp create mode 100644 module-sys/PhoneModes/Observer.hpp create mode 100644 module-sys/PhoneModes/Subject.cpp create mode 100644 module-sys/PhoneModes/Subject.hpp create mode 100644 module-sys/SystemManager/messages/PhoneModeRequest.hpp diff --git a/module-services/service-appmgr/model/ApplicationManager.cpp b/module-services/service-appmgr/model/ApplicationManager.cpp index 5ef9b5c0674ec628f68b56b677466ed9a473eca6..7feb4364bd470881c54a687451bb6cc58ecc56c1 100644 --- a/module-services/service-appmgr/model/ApplicationManager.cpp +++ b/module-services/service-appmgr/model/ApplicationManager.cpp @@ -107,8 +107,10 @@ namespace app::manager blockingTimer{std::make_unique( timerBlock, this, std::numeric_limits::max(), sys::Timer::Type::SingleShot)}, shutdownDelay{std::make_unique(timerShutdownDelay, this, shutdown_delay_ms)}, - settings(std::make_unique(this)) + settings(std::make_unique(this)), + phoneModeObserver(std::make_unique()) { + bus.channels.push_back(sys::BusChannel::PhoneModeChanges); registerMessageHandlers(); blockingTimer->connect([this](sys::Timer &) { onPhoneLocked(); }); } @@ -195,6 +197,12 @@ namespace app::manager void ApplicationManager::registerMessageHandlers() { + phoneModeObserver->connect(this); + phoneModeObserver->subscribe( + [](sys::phone_modes::PhoneMode phoneMode, sys::phone_modes::Tethering tetheringMode) { + LOG_INFO("Phone mode changed."); + }); + connect(typeid(ApplicationStatusRequest), [this](sys::Message *request) { auto msg = static_cast(request); return std::make_shared(msg->checkAppName, diff --git a/module-services/service-appmgr/service-appmgr/model/ApplicationManager.hpp b/module-services/service-appmgr/service-appmgr/model/ApplicationManager.hpp index 16138291f3ef3c82512881809da798fbaa006b59..d78d7aa9bb12be27108f802eb9f397a6dcbf394b 100644 --- a/module-services/service-appmgr/service-appmgr/model/ApplicationManager.hpp +++ b/module-services/service-appmgr/service-appmgr/model/ApplicationManager.hpp @@ -14,6 +14,7 @@ #include #include #include +#include #include #include @@ -154,6 +155,7 @@ namespace app::manager std::tuple pendingAction; std::unique_ptr settings; + std::unique_ptr phoneModeObserver; void displayLanguageChanged(std::string value); void lockTimeChanged(std::string value); void inputLanguageChanged(std::string value); diff --git a/module-services/service-evtmgr/EventManager.cpp b/module-services/service-evtmgr/EventManager.cpp index be538a5f6537d299e73c16333e208145a4333eac..201e2bae0e19667380789dec8fa481a816046070 100644 --- a/module-services/service-evtmgr/EventManager.cpp +++ b/module-services/service-evtmgr/EventManager.cpp @@ -40,6 +40,7 @@ #include #include #include +#include EventManager::EventManager(const std::string &name) : sys::Service(name), screenLightControl(std::make_unique(this)) @@ -102,9 +103,16 @@ sys::MessagePointer EventManager::DataReceivedHandler(sys::DataMessage *msgl, sy auto message = std::make_shared(); message->key = msg->key; - if (message->key.state == RawKey::State::Pressed && message->key.key_code == bsp::KeyCodes::FnRight) { - // and state == ShutDown - bus.sendUnicast(message, service::name::system_manager); + if (message->key.state == RawKey::State::Pressed) { + const auto code = message->key.key_code; + if (code == bsp::KeyCodes::FnRight) { + bus.sendUnicast(message, service::name::system_manager); + } + else if (code == bsp::KeyCodes::SSwitchUp || code == bsp::KeyCodes::SSwitchMid || + code == bsp::KeyCodes::SSwitchDown) { + const auto mode = sys::SystemManager::translateSliderState(message->key); + bus.sendUnicast(std::make_shared(mode), service::name::system_manager); + } } // send key to focused application diff --git a/module-sys/CMakeLists.txt b/module-sys/CMakeLists.txt index e200ea7eec973876dec3d0b67a65efe041b4b205..88fbed922c8df52ed41781c5216c0950d8241928 100644 --- a/module-sys/CMakeLists.txt +++ b/module-sys/CMakeLists.txt @@ -14,6 +14,8 @@ set(SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/Service/Service.cpp ${CMAKE_CURRENT_SOURCE_DIR}/Service/Timer.cpp ${CMAKE_CURRENT_SOURCE_DIR}/Service/CpuSentinel.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/PhoneModes/Subject.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/PhoneModes/Observer.cpp ${CMAKE_CURRENT_SOURCE_DIR}/SystemManager/SystemManager.cpp ${CMAKE_CURRENT_SOURCE_DIR}/SystemManager/DependencyGraph.cpp ${CMAKE_CURRENT_SOURCE_DIR}/SystemManager/PowerManager.cpp diff --git a/module-sys/PhoneModes/Common.hpp b/module-sys/PhoneModes/Common.hpp new file mode 100644 index 0000000000000000000000000000000000000000..e6ce860930945f48700dc8db31a14762fd912357 --- /dev/null +++ b/module-sys/PhoneModes/Common.hpp @@ -0,0 +1,49 @@ +// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved. +// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md + +#pragma once + +#include + +namespace sys::phone_modes +{ + enum class PhoneMode + { + Connected, + DoNotDisturb, + Offline + }; + + enum class Tethering + { + Off, + On + }; + + class PhoneModeChanged : public DataMessage + { + public: + PhoneModeChanged(PhoneMode phoneMode, Tethering tetheringMode) + : DataMessage{MessageType::MessageTypeUninitialized}, phoneMode{phoneMode}, tethering{tetheringMode} + {} + + [[nodiscard]] auto getPhoneMode() const noexcept + { + return phoneMode; + } + [[nodiscard]] auto getTetheringMode() const noexcept + { + return tethering; + } + + private: + PhoneMode phoneMode; + Tethering tethering; + }; + + class PhoneModeChangedSuccessfully : public ResponseMessage + {}; + + class PhoneModeChangeFailed : public ResponseMessage + {}; +} // namespace sys::phone_modes diff --git a/module-sys/PhoneModes/Observer.cpp b/module-sys/PhoneModes/Observer.cpp new file mode 100644 index 0000000000000000000000000000000000000000..e91904744c74f78d803728e3ee64a3043423d8fa --- /dev/null +++ b/module-sys/PhoneModes/Observer.cpp @@ -0,0 +1,70 @@ +// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved. +// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md + +#include "Observer.hpp" + +#include + +namespace sys::phone_modes +{ + void Observer::connect(Service *owner) + { + owner->connect(typeid(PhoneModeChanged), [this](sys::Message *request) -> sys::MessagePointer { + return handlePhoneModeChange(static_cast(request)); + }); + } + + void Observer::subscribe(OnChangeCallback &&onChange, + OnCompleteCallback &&onComplete, + OnErrorCallback &&onError) noexcept + { + onChangeCallback = std::move(onChange); + onCompleteCallback = std::move(onComplete); + onErrorCallback = std::move(onError); + } + + bool Observer::isInMode(PhoneMode mode) const noexcept + { + return phoneMode == mode; + } + + bool Observer::isTetheringOn() const noexcept + { + return tetheringMode == Tethering::On; + } + + sys::MessagePointer Observer::handlePhoneModeChange(PhoneModeChanged *message) + { + phoneMode = message->getPhoneMode(); + tetheringMode = message->getTetheringMode(); + + try { + onPhoneModeChanged(); + } + catch (const std::exception &) { + return std::make_shared(); + } + return std::make_shared(); + } + + void Observer::onPhoneModeChanged() + { + if (!onChangeCallback) { + LOG_WARN("No subscriber on phone mode change."); + return; + } + + try { + onChangeCallback(phoneMode, tetheringMode); + if (onCompleteCallback) { + onCompleteCallback(); + } + } + catch (const std::exception &error) { + if (onErrorCallback) { + onErrorCallback(error); + } + throw; + } + } +} // namespace sys::phone_modes diff --git a/module-sys/PhoneModes/Observer.hpp b/module-sys/PhoneModes/Observer.hpp new file mode 100644 index 0000000000000000000000000000000000000000..d56e15b6e43b760732f6eeb1bc76b59222a34a4d --- /dev/null +++ b/module-sys/PhoneModes/Observer.hpp @@ -0,0 +1,43 @@ +// 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 "Common.hpp" + +namespace sys +{ + class Service; // Forward declaration +} // namespace sys + +namespace sys::phone_modes +{ + class Observer + { + public: + using OnChangeCallback = std::function; + using OnCompleteCallback = std::function; + using OnErrorCallback = std::function; + + void connect(Service *owner); + void subscribe(OnChangeCallback &&onChange, + OnCompleteCallback &&onComplete = {}, + OnErrorCallback &&onError = {}) noexcept; + + bool isInMode(PhoneMode mode) const noexcept; + bool isTetheringOn() const noexcept; + + private: + sys::MessagePointer handlePhoneModeChange(PhoneModeChanged *message); + void onPhoneModeChanged(); + + OnChangeCallback onChangeCallback; + OnCompleteCallback onCompleteCallback; + OnErrorCallback onErrorCallback; + PhoneMode phoneMode = PhoneMode::Connected; + Tethering tetheringMode = Tethering::Off; + }; +} // namespace sys::phone_modes diff --git a/module-sys/PhoneModes/Subject.cpp b/module-sys/PhoneModes/Subject.cpp new file mode 100644 index 0000000000000000000000000000000000000000..fa74c5445de28af0e4307fce016d760ef5963e33 --- /dev/null +++ b/module-sys/PhoneModes/Subject.cpp @@ -0,0 +1,61 @@ +// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved. +// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md + +#include "Subject.hpp" + +#include + +#include + +#include +#include + +namespace sys::phone_modes +{ + Subject::Subject(Service *owner) : owner{owner} + { + if (owner == nullptr) { + throw std::invalid_argument{"Subject's owner is invalid"}; + } + } + + void Subject::setMode(PhoneMode _phoneMode, Tethering _tetheringMode) + { + if (const bool changed = changePhoneMode(_phoneMode) || changeTetheringMode(_tetheringMode); changed) { + notifyChange(); + } + } + + void Subject::setPhoneMode(PhoneMode mode) + { + if (const auto changed = changePhoneMode(mode); changed) { + notifyChange(); + } + } + + bool Subject::changePhoneMode(PhoneMode mode) noexcept + { + return std::exchange(phoneMode, mode) != mode; + } + + void Subject::setTetheringMode(Tethering mode) + { + if (const auto changed = changeTetheringMode(mode); changed) { + notifyChange(); + } + } + + bool Subject::changeTetheringMode(Tethering mode) noexcept + { + return std::exchange(tetheringMode, mode) != mode; + } + + void Subject::notifyChange() + { + LOG_INFO("Phone modes changed: Phone mode: [%s]; Tethering: [%s]. Notifying phone modes observers.", + magic_enum::enum_name(phoneMode).data(), + magic_enum::enum_name(tetheringMode).data()); + auto message = std::make_shared(phoneMode, tetheringMode); + owner->bus.sendMulticast(std::move(message), BusChannel::PhoneModeChanges); + } +} // namespace sys::phone_modes diff --git a/module-sys/PhoneModes/Subject.hpp b/module-sys/PhoneModes/Subject.hpp new file mode 100644 index 0000000000000000000000000000000000000000..ff6f383f1a38b3a3f9879ecbd09a9591004569a5 --- /dev/null +++ b/module-sys/PhoneModes/Subject.hpp @@ -0,0 +1,33 @@ +// 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 "Common.hpp" + +namespace sys +{ + class Service; // Forward declaration +} // namespace sys + +namespace sys::phone_modes +{ + class Subject + { + public: + explicit Subject(Service *owner); + + void setMode(PhoneMode _phoneMode, Tethering _tetheringMode); + void setPhoneMode(PhoneMode mode); + void setTetheringMode(Tethering mode); + + private: + void notifyChange(); + bool changePhoneMode(PhoneMode mode) noexcept; + bool changeTetheringMode(Tethering mode) noexcept; + + Service *owner; + PhoneMode phoneMode = PhoneMode::Connected; + Tethering tetheringMode = Tethering::Off; + }; +} // namespace sys::phone_modes diff --git a/module-sys/Service/Common.hpp b/module-sys/Service/Common.hpp index 01a825c2f22b9fdac4472727fa700c3ffa94a0ff..379ffbad625acdbb646075d34865390815136381 100644 --- a/module-sys/Service/Common.hpp +++ b/module-sys/Service/Common.hpp @@ -21,7 +21,8 @@ namespace sys ServiceFotaNotifications, AntennaNotifications, ServiceEvtmgrNotifications, - CalendarNotifications + CalendarNotifications, + PhoneModeChanges, }; enum class ServicePriority @@ -111,6 +112,8 @@ inline const char *c_str(sys::BusChannel channel) return "ServiceEvtmgrNotifications"; case sys::BusChannel::CalendarNotifications: return "CalendarNotifications"; + case sys::BusChannel::PhoneModeChanges: + return "PhoneModeChanges"; } return ""; } diff --git a/module-sys/SystemManager/SystemManager.cpp b/module-sys/SystemManager/SystemManager.cpp index dc7f58207e8776ae8d04e85d11841352e183a591..c09fa581c0e4c7a11a953b1c81c373e0a338a38b 100644 --- a/module-sys/SystemManager/SystemManager.cpp +++ b/module-sys/SystemManager/SystemManager.cpp @@ -25,12 +25,20 @@ #include "messages/DeviceRegistrationMessage.hpp" #include "messages/SentinelRegistrationMessage.hpp" #include "messages/RequestCpuFrequencyMessage.hpp" +#include "messages/PhoneModeRequest.hpp" #include