~aleteoryx/muditaos

4175025f36562a63ba638654684190cdd62d938a — Piotr Tański 4 years ago e0fae08
[EGD-776] PreWakeUp chime

Added a prewakeup chime handler.
M module-services/service-time/AlarmMessageHandler.cpp => module-services/service-time/AlarmMessageHandler.cpp +0 -6
@@ 111,12 111,6 @@ namespace alarms
        alarmOperations->addSnoozedAlarmsCountChangeCallback(callback);
    }

    auto AlarmMessageHandler::addAlarmExecutionHandler(const alarms::AlarmType type,
                                                       const std::shared_ptr<alarms::AlarmHandler> handler) -> void
    {
        alarmOperations->addAlarmExecutionHandler(type, handler);
    }

    template <class RequestType, class ResponseType, class CallbackParamType>
    auto AlarmMessageHandler::handleWithCallback(
        RequestType *request,

M module-services/service-time/AlarmMessageHandler.hpp => module-services/service-time/AlarmMessageHandler.hpp +0 -3
@@ 38,9 38,6 @@ namespace alarms
        auto handleAddSnoozedAlarmCountChangeCallback(AlarmOperationsCommon::OnSnoozedAlarmsCountChange callback)
            -> void;

        auto addAlarmExecutionHandler(const alarms::AlarmType type, const std::shared_ptr<alarms::AlarmHandler> handler)
            -> void;

      private:
        stm::ServiceTime *service = nullptr;
        std::unique_ptr<IAlarmOperations> alarmOperations;

M module-services/service-time/ServiceTime.cpp => module-services/service-time/ServiceTime.cpp +7 -14
@@ 34,17 34,13 @@ namespace stm
    constexpr auto automaticTimezoneName  = "";
    constexpr auto automaticTimezoneRules = "UTC0";

    ServiceTime::ServiceTime(const alarms::IAlarmOperationsFactory &alarmOperationsFactory)
    ServiceTime::ServiceTime(std::shared_ptr<alarms::IAlarmOperationsFactory> alarmOperationsFactory)
        : sys::Service(service::name::service_time, "", StackDepth), timeManager{std::make_unique<TimeManager>(
                                                                         std::make_unique<RTCCommand>(this))}
                                                                         std::make_unique<RTCCommand>(this))},
          alarmOperationsFactory{std::move(alarmOperationsFactory)}
    {
        LOG_INFO("[ServiceTime] Initializing");
        bus.channels.push_back(sys::BusChannel::ServiceDBNotifications);

        auto alarmEventsRepo = std::make_unique<alarms::AlarmEventsDBRepository>(this);
        auto alarmOperations = alarmOperationsFactory.create(this, std::move(alarmEventsRepo), TimePointNow);
        alarmOperations->updateEventsCache(TimePointNow());
        alarmMessageHandler = std::make_unique<alarms::AlarmMessageHandler>(this, std::move(alarmOperations));
    }

    ServiceTime::~ServiceTime()


@@ 61,8 57,11 @@ namespace stm
        static TimeSettings timeSettings;
        utils::time::TimestampFactory().init(&timeSettings);

        auto alarmEventsRepo = std::make_unique<alarms::AlarmEventsDBRepository>(this);
        auto alarmOperations = alarmOperationsFactory->create(this, std::move(alarmEventsRepo), TimePointNow);
        alarmOperations->updateEventsCache(TimePointNow());
        alarmMessageHandler = std::make_unique<alarms::AlarmMessageHandler>(this, std::move(alarmOperations));
        registerMessageHandlers();

        return sys::ReturnCodes::Success;
    }



@@ 103,12 102,6 @@ namespace stm
        }
    }

    void ServiceTime::addAlarmExecutionHandler(const alarms::AlarmType type,
                                               const std::shared_ptr<alarms::AlarmHandler> handler)
    {
        alarmMessageHandler->addAlarmExecutionHandler(type, handler);
    }

    void ServiceTime::registerMessageHandlers()
    {
        connect(typeid(CellularTimeNotificationMessage), [&](sys::Message *request) -> sys::MessagePointer {

M module-services/service-time/ServiceTime.hpp => module-services/service-time/ServiceTime.hpp +4 -5
@@ 38,6 38,8 @@ namespace stm

        std::unique_ptr<alarms::AlarmMessageHandler> alarmMessageHandler;

        std::shared_ptr<alarms::IAlarmOperationsFactory> alarmOperationsFactory;

        void registerMessageHandlers();
        auto handleSetAutomaticDateAndTimeRequest(sys::Message *request) -> std::shared_ptr<sys::ResponseMessage>;
        auto handleSetTimeFormatRequest(sys::Message *request) -> std::shared_ptr<sys::ResponseMessage>;


@@ 49,8 51,8 @@ namespace stm
        void initStaticData();

      public:
        ServiceTime(
            const alarms::IAlarmOperationsFactory &alarmOperationsFactory = alarms::CommonAlarmOperationsFactory{});
        ServiceTime(std::shared_ptr<alarms::IAlarmOperationsFactory> alarmOperationsFactory =
                        std::make_shared<alarms::CommonAlarmOperationsFactory>());
        ~ServiceTime();

        sys::ReturnCodes InitHandler() override;


@@ 59,9 61,6 @@ namespace stm
        sys::ReturnCodes SwitchPowerModeHandler(const sys::ServicePowerMode mode) override final;

        sys::MessagePointer DataReceivedHandler(sys::DataMessage *msgl, sys::ResponseMessage *resp = nullptr) override;

        void addAlarmExecutionHandler(const alarms::AlarmType type,
                                      const std::shared_ptr<alarms::AlarmHandler> handler);
    };

} /* namespace stm */

M module-sys/Service/include/Service/ServiceCreator.hpp => module-sys/Service/include/Service/ServiceCreator.hpp +1 -2
@@ 51,8 51,7 @@ namespace sys

        [[nodiscard]] auto create() const -> std::shared_ptr<Service> override
        {
            return std::apply([](auto... args) { return std::make_shared<T, Args...>(std::forward<Args>(args)...); },
                              savedArgs);
            return std::apply([](auto... args) { return std::make_shared<T>(std::forward<Args>(args)...); }, savedArgs);
        }

      private:

M products/BellHybrid/BellHybridMain.cpp => products/BellHybrid/BellHybridMain.cpp +1 -1
@@ 68,7 68,7 @@ int main()
    systemServices.emplace_back(sys::CreatorFor<ServiceDB>());
    systemServices.emplace_back(sys::CreatorFor<ServiceAudio>());
    systemServices.emplace_back(sys::CreatorFor<ServiceDesktop>());
    systemServices.emplace_back(sys::CreatorFor<stm::ServiceTime>(alarms::AlarmOperationsFactory{}));
    systemServices.emplace_back(sys::CreatorFor<stm::ServiceTime>(std::make_shared<alarms::AlarmOperationsFactory>()));
    systemServices.emplace_back(sys::CreatorFor<service::eink::ServiceEink>());
    systemServices.emplace_back(sys::CreatorFor<service::gui::ServiceGUI>());


M products/BellHybrid/alarms/BellAlarmHandler.cpp => products/BellHybrid/alarms/BellAlarmHandler.cpp +17 -44
@@ 2,82 2,55 @@
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include "BellAlarmHandler.hpp"
#include "src/actions/PlayToneAction.hpp"
#include "src/actions/PlayAudioActions.hpp"
#include "src/actions/NotifyGUIAction.hpp"
#include "src/actions/FrontlightAction.hpp"

namespace alarms
{
    BellAlarmClockHandler::BellAlarmClockHandler(sys::Service *service) : service{service}
    {
        actions.emplace_back(std::make_unique<PlayToneAction>(*service));
        actions.emplace_back(std::make_unique<NotifyGUIAction>(*service));
        actions.emplace_back(std::make_unique<FrontlightAction>());
    }
    BellAlarmHandler::BellAlarmHandler(Actions &&actions) : actions{std::move(actions)}
    {}

    auto BellAlarmClockHandler::handle(const AlarmEventRecord &record) -> bool
    bool BellAlarmHandler::handle(const AlarmEventRecord &record)
    {
        LOG_DEBUG("BellAlarmClockHandler");

        auto result{true};

        if (record.enabled) {
            for (const auto &action : actions) {
                result &= action->execute();
            }
        }

        return result;
    }

    auto BellAlarmClockHandler::handleOff([[maybe_unused]] const AlarmEventRecord &record) -> bool
    bool BellAlarmHandler::handleOff([[maybe_unused]] const AlarmEventRecord &record)
    {
        auto result{true};
        for (const auto &action : actions) {
            result &= action->turnOff();
        }

        return result;
    }

    auto EveningReminderHandler::handle([[maybe_unused]] const AlarmEventRecord &record) -> bool
    {
        // implement this alarm type handling here
        return true;
    }

    auto EveningReminderHandler::handleOff([[maybe_unused]] const AlarmEventRecord &record) -> bool
    {
        return true;
    }

    PreWakeUpChimeHandler::PreWakeUpChimeHandler(sys::Service *service) : service{service}
    {}

    auto PreWakeUpChimeHandler::handle(const AlarmEventRecord &record) -> bool
    BellAlarmClockHandler::BellAlarmClockHandler(sys::Service *service) : BellAlarmHandler{getActions(service)}
    {
        LOG_INFO("PreWakeUpChimeHandler::handle");
        return true;
    }

    auto PreWakeUpChimeHandler::handleOff(const AlarmEventRecord &record) -> bool
    auto BellAlarmClockHandler::getActions(sys::Service *service) -> Actions
    {
        LOG_INFO("PreWakeUpChimeHandler::handleOff");
        return true;
        Actions actions;
        actions.emplace_back(std::make_unique<PlayToneAction>(*service));
        actions.emplace_back(std::make_unique<NotifyGUIAction>(*service));
        actions.emplace_back(std::make_unique<FrontlightAction>());
        return actions;
    }

    PreWakeUpFrontlightHandler::PreWakeUpFrontlightHandler(sys::Service *service) : service{service}
    PreWakeUpChimeHandler::PreWakeUpChimeHandler(sys::Service *service) : BellAlarmHandler{getActions(service)}
    {}

    auto PreWakeUpFrontlightHandler::handle(const AlarmEventRecord &record) -> bool
    {
        LOG_INFO("PreWakeUpFrontlightHandler::handle");
        return true;
    }

    auto PreWakeUpFrontlightHandler::handleOff(const AlarmEventRecord &record) -> bool
    auto PreWakeUpChimeHandler::getActions(sys::Service *service) -> Actions
    {
        LOG_INFO("PreWakeUpFrontlightHandler::handleOff");
        return true;
        Actions actions;
        actions.emplace_back(std::make_unique<PlayChimeAction>(*service));
        return actions;
    }
} // namespace alarms

M products/BellHybrid/alarms/CMakeLists.txt => products/BellHybrid/alarms/CMakeLists.txt +2 -2
@@ 4,13 4,13 @@ add_library(bell::alarms ALIAS alarms)
target_sources(alarms
    PRIVATE
        BellAlarmHandler.cpp
        src/actions/PlayToneAction.cpp
        src/actions/PlayAudioActions.cpp
        src/actions/NotifyGUIAction.cpp
        src/actions/FrontlightAction.cpp

        include/AbstractAlarmAction.hpp
        include/BellAlarmHandler.hpp
        src/actions/PlayToneAction.hpp
        src/actions/PlayAudioActions.hpp
        src/actions/FrontlightAction.hpp
        src/actions/NotifyGUIAction.hpp
    PUBLIC

M products/BellHybrid/alarms/include/BellAlarmHandler.hpp => products/BellHybrid/alarms/include/BellAlarmHandler.hpp +12 -28
@@ 9,50 9,34 @@

namespace alarms
{
    class BellAlarmClockHandler : public AlarmHandler
    class BellAlarmHandler : public AlarmHandler
    {
      public:
        explicit BellAlarmClockHandler(sys::Service *service);
        auto handle(const AlarmEventRecord &record) -> bool;
        auto handleOff(const AlarmEventRecord &record) -> bool;
        using Actions = std::vector<std::unique_ptr<AbstractAlarmAction>>;

        static constexpr auto name = "BellAlarmClockHandler";
        explicit BellAlarmHandler(Actions &&actions = {});
        bool handle(const AlarmEventRecord &record) override;
        bool handleOff(const AlarmEventRecord &record) override;

      private:
        sys::Service *service{};
        std::vector<std::unique_ptr<AbstractAlarmAction>> actions;
    };

    class EveningReminderHandler : public AlarmHandler
    {
      public:
        auto handle(const AlarmEventRecord &record) -> bool;
        auto handleOff(const AlarmEventRecord &record) -> bool;
        Actions actions;
    };

    class PreWakeUpChimeHandler : public AlarmHandler
    class BellAlarmClockHandler : public BellAlarmHandler
    {
      public:
        explicit PreWakeUpChimeHandler(sys::Service *service);
        auto handle(const AlarmEventRecord &record) -> bool;
        auto handleOff(const AlarmEventRecord &record) -> bool;

        static constexpr auto name = "PreWakeUpChimeHandler";
        explicit BellAlarmClockHandler(sys::Service *service);

      private:
        sys::Service *service{};
        static auto getActions(sys::Service *service) -> Actions;
    };

    class PreWakeUpFrontlightHandler : public AlarmHandler
    class PreWakeUpChimeHandler : public BellAlarmHandler
    {
      public:
        explicit PreWakeUpFrontlightHandler(sys::Service *service);
        auto handle(const AlarmEventRecord &record) -> bool;
        auto handleOff(const AlarmEventRecord &record) -> bool;

        static constexpr auto name = "PreWakeUpFrontlightHandler";
        explicit PreWakeUpChimeHandler(sys::Service *service);

      private:
        sys::Service *service{};
        static auto getActions(sys::Service *service) -> Actions;
    };
} // namespace alarms

R products/BellHybrid/alarms/src/actions/PlayToneAction.cpp => products/BellHybrid/alarms/src/actions/PlayAudioActions.cpp +37 -17
@@ 1,7 1,7 @@
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include "PlayToneAction.hpp"
#include "PlayAudioActions.hpp"
#include <purefs/filesystem_paths.hpp>
#include <service-audio/AudioServiceAPI.hpp>
#include <service-time/ServiceTime.hpp>


@@ 16,35 16,30 @@ namespace

namespace alarms
{
    alarms::PlayToneAction::PlayToneAction(sys::Service &service) : service{service}
    {
        settings.init(service::ServiceProxy{service.weak_from_this()});
    }
    bool alarms::PlayToneAction::execute()
    {
        const auto valueStr = settings.getValue(bell::settings::Ringing::duration, settings::SettingsScope::Global);
        const auto ringingDuration = std::chrono::seconds{utils::getNumericValue<uint32_t>(valueStr)};
        const auto tone            = settings.getValue(bell::settings::Ringing::tone, settings::SettingsScope::Global);
        const auto tonePath        = std::filesystem::path{purefs::dir::getUserDiskPath().string() + musicDir + tone};
    PlayAudioAction::PlayAudioAction(sys::Service &service) : service{service}
    {}

        spawnTimer(ringingDuration);

        return AudioServiceAPI::PlaybackStart(&service, audio::PlaybackType::Alarm, tonePath);
    bool PlayAudioAction::play(const std::filesystem::path &path, std::chrono::seconds duration)
    {
        if (duration != InfiniteDuration) {
            spawnTimer(duration);
        }
        return AudioServiceAPI::PlaybackStart(&service, audio::PlaybackType::Alarm, path);
    }

    bool alarms::PlayToneAction::turnOff()
    bool PlayAudioAction::turnOff()
    {
        return true;
    }

    void PlayToneAction::detachTimer()
    void PlayAudioAction::detachTimer()
    {
        if (timer.isValid()) {
            timer.stop();
            timer.reset();
        }
    }
    void PlayToneAction::spawnTimer(std::chrono::seconds timeout)
    void PlayAudioAction::spawnTimer(std::chrono::seconds timeout)
    {
        if (not timer.isValid()) {
            auto callback = [this](sys::Timer &) { AudioServiceAPI::Stop(&service, {audio::PlaybackType::Alarm}); };


@@ 54,4 49,29 @@ namespace alarms
        timer.start();
    }

    PlayToneAction::PlayToneAction(sys::Service &service) : PlayAudioAction{service}
    {
        settings.init(service::ServiceProxy{service.weak_from_this()});
    }

    bool PlayToneAction::execute()
    {
        const auto tone     = settings.getValue(bell::settings::Ringing::tone, settings::SettingsScope::Global);
        const auto tonePath = std::filesystem::path{purefs::dir::getUserDiskPath().string() + musicDir + tone};
        const auto valueStr = settings.getValue(bell::settings::Ringing::duration, settings::SettingsScope::Global);
        const auto ringingDuration = std::chrono::seconds{utils::getNumericValue<uint32_t>(valueStr)};
        return play(tonePath, ringingDuration);
    }

    PlayChimeAction::PlayChimeAction(sys::Service &service) : PlayAudioAction{service}
    {
        settings.init(service::ServiceProxy{service.weak_from_this()});
    }

    bool PlayChimeAction::execute()
    {
        const auto tone     = settings.getValue(bell::settings::Ringing::tone, settings::SettingsScope::Global);
        const auto tonePath = std::filesystem::path{purefs::dir::getUserDiskPath().string() + musicDir + tone};
        return play(tonePath);
    }
} // namespace alarms

R products/BellHybrid/alarms/src/actions/PlayToneAction.hpp => products/BellHybrid/alarms/src/actions/PlayAudioActions.hpp +29 -4
@@ 8,22 8,47 @@
#include <Timers/TimerHandle.hpp>
#include <Service/Service.hpp>

#include <chrono>
#include <filesystem>

namespace alarms
{
    class PlayToneAction : public AbstractAlarmAction
    class PlayAudioAction : public AbstractAlarmAction
    {
      public:
        explicit PlayToneAction(sys::Service &service);
        bool execute() override;
        bool turnOff() override;

      protected:
        explicit PlayAudioAction(sys::Service &service);

        static constexpr auto InfiniteDuration = std::chrono::seconds::max();
        bool play(const std::filesystem::path &path, std::chrono::seconds duration = InfiniteDuration);

      private:
        void spawnTimer(std::chrono::seconds timeout);
        void detachTimer();

        sys::Service &service;
        settings::Settings settings;
        sys::TimerHandle timer;
    };

    class PlayToneAction : public PlayAudioAction
    {
      public:
        explicit PlayToneAction(sys::Service &service);
        bool execute() override;

      private:
        settings::Settings settings;
    };

    class PlayChimeAction : public PlayAudioAction
    {
      public:
        explicit PlayChimeAction(sys::Service &service);
        bool execute() override;

      private:
        settings::Settings settings;
    };
} // namespace alarms

M products/BellHybrid/services/time/AlarmOperations.cpp => products/BellHybrid/services/time/AlarmOperations.cpp +26 -12
@@ 5,23 5,37 @@

#include <BellAlarmHandler.hpp>

#include <service-db/Settings.hpp>

namespace alarms
{
    namespace
    {
        class FakePreWakeUpSettingsProvider : public PreWakeUpSettingsProvider
        class PreWakeUpSettingsProviderImpl : public PreWakeUpSettingsProvider
        {
          public:
            auto getChimeSettings() -> Settings override
            {
                return {true, std::chrono::minutes{5}};
            }
            explicit PreWakeUpSettingsProviderImpl(sys::Service *service);
            auto getChimeSettings() -> Settings override;
            auto getFrontlightSettings() -> Settings override;

            auto getFrontlightSettings() -> Settings override
            {
                return {true, std::chrono::minutes{5}};
            }
          private:
            settings::Settings settings;
        };

        PreWakeUpSettingsProviderImpl::PreWakeUpSettingsProviderImpl(sys::Service *service)
        {
            settings.init(service::ServiceProxy{service->weak_from_this()});
        }

        auto PreWakeUpSettingsProviderImpl::getChimeSettings() -> Settings
        {
            return {true, std::chrono::minutes{5}};
        }

        auto PreWakeUpSettingsProviderImpl::getFrontlightSettings() -> Settings
        {
            return {true, std::chrono::minutes{5}};
        }
    } // namespace

    std::unique_ptr<IAlarmOperations> AlarmOperationsFactory::create(


@@ 29,13 43,13 @@ namespace alarms
        std::unique_ptr<AbstractAlarmEventsRepository> &&alarmEventsRepo,
        IAlarmOperations::GetCurrentTime getCurrentTimeCallback) const
    {
        auto settingsProvider = std::make_unique<FakePreWakeUpSettingsProvider>();
        auto settingsProvider = std::make_unique<PreWakeUpSettingsProviderImpl>(service);
        auto alarmOperations  = std::make_unique<AlarmOperations>(
            std::move(alarmEventsRepo), getCurrentTimeCallback, std::move(settingsProvider));
        alarmOperations->addAlarmExecutionHandler(alarms::AlarmType::Clock,
                                                  std::make_shared<alarms::BellAlarmClockHandler>(service));
        alarmOperations->addAlarmExecutionHandler(alarms::AlarmType::PreWakeUpChime,
                                                  std::make_shared<alarms::PreWakeUpChimeHandler>(service));
        alarmOperations->addAlarmExecutionHandler(alarms::AlarmType::PreWakeUpFrontlight,
                                                  std::make_shared<alarms::PreWakeUpFrontlightHandler>(service));
        return alarmOperations;
    }