~aleteoryx/muditaos

2b42e8e31dd11e45651a656a48d4c2a3d36bb6fe — Tigran Soghbatyan 4 years ago 55eff92
[BH-773] Add bedtime reminder application

Add bedtime time and on/off UI setup app
Add bedtime event notification window
Add bedtime audio assets
Implement bedtime notification TimeService backend
Add bedtime unittests
64 files changed, 1242 insertions(+), 30 deletions(-)

M image/assets/lang/English.json
M image/assets/lang/Polski.json
M module-apps/apps-common/popups/Popups.cpp
M module-apps/apps-common/popups/Popups.hpp
M module-services/service-time/include/service-time/AlarmHandler.hpp
M products/BellHybrid/BellHybridMain.cpp
M products/BellHybrid/CMakeLists.txt
M products/BellHybrid/alarms/BellAlarmHandler.cpp
M products/BellHybrid/alarms/CMakeLists.txt
M products/BellHybrid/alarms/include/AlarmSoundPaths.hpp
M products/BellHybrid/alarms/include/BellAlarmHandler.hpp
A products/BellHybrid/alarms/include/popups/BedtimeReminderPopupRequestParams.hpp
M products/BellHybrid/alarms/src/AlarmSoundPaths.cpp
A products/BellHybrid/alarms/src/actions/NotifyGUIBedtimeReminderAction.cpp
A products/BellHybrid/alarms/src/actions/NotifyGUIBedtimeReminderAction.hpp
M products/BellHybrid/alarms/src/actions/PlayAudioActions.cpp
M products/BellHybrid/alarms/src/actions/PlayAudioActions.hpp
M products/BellHybrid/apps/Application.cpp
M products/BellHybrid/apps/CMakeLists.txt
M products/BellHybrid/apps/application-bell-alarm/ApplicationBellAlarm.cpp
M products/BellHybrid/apps/application-bell-background-sounds/ApplicationBellBackgroundSounds.cpp
A products/BellHybrid/apps/application-bell-bedtime/ApplicationBellBedtime.cpp
A products/BellHybrid/apps/application-bell-bedtime/CMakeLists.txt
A products/BellHybrid/apps/application-bell-bedtime/data/BellBedtimeStyle.hpp
A products/BellHybrid/apps/application-bell-bedtime/include/application-bell-bedtime/ApplicationBellBedtime.hpp
A products/BellHybrid/apps/application-bell-bedtime/models/BedtimeListItemProvider.cpp
A products/BellHybrid/apps/application-bell-bedtime/models/BedtimeListItemProvider.hpp
A products/BellHybrid/apps/application-bell-bedtime/presenter/BellBedtimeWindowPresenter.cpp
A products/BellHybrid/apps/application-bell-bedtime/presenter/BellBedtimeWindowPresenter.hpp
A products/BellHybrid/apps/application-bell-bedtime/windows/BellBedtimeWindow.cpp
A products/BellHybrid/apps/application-bell-bedtime/windows/BellBedtimeWindow.hpp
M products/BellHybrid/apps/application-bell-main/ApplicationBellMain.cpp
M products/BellHybrid/apps/application-bell-main/CMakeLists.txt
M products/BellHybrid/apps/application-bell-main/include/application-bell-main/ApplicationBellMain.hpp
M products/BellHybrid/apps/application-bell-main/windows/BellMainMenuWindow.cpp
M products/BellHybrid/apps/application-bell-powernap/ApplicationBellPowerNap.cpp
M products/BellHybrid/apps/application-bell-settings/ApplicationBellSettings.cpp
M products/BellHybrid/apps/application-bell-settings/CMakeLists.txt
M products/BellHybrid/apps/application-bell-settings/data/BellSettingsStyle.hpp
M products/BellHybrid/apps/application-bell-settings/models/alarm_settings/AlarmSettingsModel.hpp
M products/BellHybrid/apps/application-bell-settings/models/alarm_settings/PrewakeUpSettingsModel.hpp
M products/BellHybrid/apps/application-bell-settings/models/alarm_settings/SnoozeSettingsModel.hpp
M products/BellHybrid/apps/common/CMakeLists.txt
A products/BellHybrid/apps/common/include/common/data/BellFinishedCallbackWindowSwitchData.hpp
A products/BellHybrid/apps/common/include/common/models/AbstractBedtimeModel.hpp
A products/BellHybrid/apps/common/include/common/models/BedtimeModel.hpp
R products/BellHybrid/apps/{application-bell-settings => common/include/common}/models/SettingsModel.hpp
A products/BellHybrid/apps/common/include/common/popups/BedtimeNotificationWindow.hpp
M products/BellHybrid/apps/common/include/common/widgets/BellSideListItemWithCallbacks.hpp
M products/BellHybrid/apps/common/include/common/widgets/ListItems.hpp
A products/BellHybrid/apps/common/include/common/windows/BellFinishedCallbackWindow.hpp
M products/BellHybrid/apps/common/src/BellSideListItemWithCallbacks.cpp
A products/BellHybrid/apps/common/src/models/BedtimeModel.cpp
R products/BellHybrid/apps/{application-bell-settings => common/src}/models/SettingsModel.cpp
A products/BellHybrid/apps/common/src/popups/BedtimeNotificationWindow.cpp
M products/BellHybrid/apps/common/src/widgets/ListItems.cpp
A products/BellHybrid/apps/common/src/windows/BellFinishedCallbackWindow.cpp
M products/BellHybrid/services/appmgr/ApplicationManager.cpp
M products/BellHybrid/services/appmgr/include/appmgr/messages/AlarmMessage.hpp
M products/BellHybrid/services/db/include/db/SystemSettings.hpp
M products/BellHybrid/services/time/AlarmOperations.cpp
M products/BellHybrid/services/time/CMakeLists.txt
M products/BellHybrid/services/time/include/time/AlarmOperations.hpp
M products/BellHybrid/services/time/tests/test-BellAlarmOperations.cpp
M image/assets/lang/English.json => image/assets/lang/English.json +2 -0
@@ 575,6 575,8 @@
  "app_bell_settings_time_units_finished_message": "Time and units are set.",
  "app_bellmain_alarm": "Alarm",
  "app_bellmain_bedtime": "Bedtime",
  "app_bell_bedtime_set_finished": "Bedtime reminder\nis set",
  "app_bell_bedtime_notification": "It is Your bedtime",
  "app_bellmain_power_nap": "Power nap",
  "app_bellmain_meditation_timer": "Meditation timer",
  "app_bellmain_background_sounds": "Background sounds",

M image/assets/lang/Polski.json => image/assets/lang/Polski.json +2 -0
@@ 590,6 590,8 @@
  "app_bell_settings_time_units_finished_message": "Czas i jednostki ustawione.",
  "app_bellmain_alarm": "Alarm",
  "app_bellmain_bedtime": "Pora snu",
  "app_bell_bedtime_set_finished": "Pora snu\nustawiona",
  "app_bell_bedtime_notification": "Pora na sen",
  "app_bellmain_power_nap": "Drzemka",
  "app_bellmain_meditation_timer": "Medytacja",
  "app_bellmain_background_sounds": "Dźwięki otoczenia",

M module-apps/apps-common/popups/Popups.cpp => module-apps/apps-common/popups/Popups.cpp +2 -0
@@ 42,6 42,8 @@ namespace gui::popup
            return gui::popup::window::power_off_window;
        case ID::Reboot:
            return gui::popup::window::reboot_window;
        case ID::BedtimeNotification:
            return gui::popup::window::bedtime_notification_window;
        }

        return {};

M module-apps/apps-common/popups/Popups.hpp => module-apps/apps-common/popups/Popups.hpp +3 -1
@@ 27,7 27,8 @@ namespace gui
            AlarmDeactivated,
            Alarm,
            PowerOff,
            Reboot
            Reboot,
            BedtimeNotification,
        };

        namespace window


@@ 50,6 51,7 @@ namespace gui
            inline constexpr auto alarm_deactivated_window          = "AlarmDeactivatedPopup";
            inline constexpr auto alarm_window                      = "AlarmPopup";
            inline constexpr auto reboot_window                     = "RebootPopup";
            inline constexpr auto bedtime_notification_window       = "BedtimeNotificationPopup";
        } // namespace window

        std::string resolveWindowName(ID id);

M module-services/service-time/include/service-time/AlarmHandler.hpp => module-services/service-time/include/service-time/AlarmHandler.hpp +2 -1
@@ 15,6 15,7 @@ namespace alarms
        PreWakeUpChime,
        PreWakeUpFrontlight,
        SnoozeChime,
        BedtimeReminder,
        None
    };



@@ 23,7 24,7 @@ namespace alarms
      public:
        virtual ~AlarmHandler() = default;

        virtual auto handle(const AlarmEventRecord &record) -> bool = 0;
        virtual auto handle(const AlarmEventRecord &record) -> bool    = 0;
        virtual auto handleOff(const AlarmEventRecord &record) -> bool = 0;
    };
} // namespace alarms

M products/BellHybrid/BellHybridMain.cpp => products/BellHybrid/BellHybridMain.cpp +2 -0
@@ 7,6 7,7 @@
#include <application-bell-alarm/ApplicationBellAlarm.hpp>
#include <application-bell-onboarding/ApplicationBellOnBoarding.hpp>
#include <application-bell-background-sounds/ApplicationBellBackgroundSounds.hpp>
#include <application-bell-bedtime/ApplicationBellBedtime.hpp>
#include <application-bell-main/ApplicationBellMain.hpp>
#include <application-bell-settings/ApplicationBellSettings.hpp>
#include <application-bell-powernap/ApplicationBellPowerNap.hpp>


@@ 97,6 98,7 @@ int main()
                app::CreateLauncher<app::ApplicationBellMain>(app::applicationBellName, app::Closeable::False));
            applications.push_back(app::CreateLauncher<app::ApplicationBellSettings>(app::applicationBellSettingsName));
            applications.push_back(app::CreateLauncher<app::ApplicationBellAlarm>(app::applicationBellAlarmName));
            applications.push_back(app::CreateLauncher<app::ApplicationBellBedtime>(app::applicationBellBedtimeName));
            applications.push_back(app::CreateLauncher<app::ApplicationBellPowerNap>(app::applicationBellPowerNapName));
            applications.push_back(
                app::CreateLauncher<app::ApplicationBellOnBoarding>(app::applicationBellOnBoardingName));

M products/BellHybrid/CMakeLists.txt => products/BellHybrid/CMakeLists.txt +1 -0
@@ 41,6 41,7 @@ target_link_libraries(BellHybrid
        bell::app-alarm
        bell::app-onboarding
        bell::app-background-sounds
        bell::app-bedtime
        bell::app-common
        bell::app-main
        bell::app-powernap

M products/BellHybrid/alarms/BellAlarmHandler.cpp => products/BellHybrid/alarms/BellAlarmHandler.cpp +13 -2
@@ 5,6 5,7 @@
#include "src/actions/PlayAudioActions.hpp"
#include "src/actions/NotifyGUIAction.hpp"
#include "src/actions/FrontlightAction.hpp"
#include "src/actions/NotifyGUIBedtimeReminderAction.hpp"

namespace alarms
{


@@ 32,8 33,7 @@ namespace alarms
    }

    BellAlarmClockHandler::BellAlarmClockHandler(sys::Service *service) : BellAlarmHandler{getActions(service)}
    {
    }
    {}

    auto BellAlarmClockHandler::getActions(sys::Service *service) -> Actions
    {


@@ 63,4 63,15 @@ namespace alarms
        actions.emplace_back(createSnoozeChimeAction(*service));
        return actions;
    }

    BedtimeReminderHandler::BedtimeReminderHandler(sys::Service *service) : BellAlarmHandler{getActions(service)}
    {}

    auto BedtimeReminderHandler::getActions(sys::Service *service) -> Actions
    {
        Actions actions;
        actions.emplace_back(createBedtimeChimeAction(*service));
        actions.emplace_back(std::make_unique<NotifyGUIBedtimeReminderAction>(*service));
        return actions;
    }
} // namespace alarms

M products/BellHybrid/alarms/CMakeLists.txt => products/BellHybrid/alarms/CMakeLists.txt +4 -0
@@ 7,6 7,7 @@ target_sources(alarms
        src/AlarmSoundPaths.cpp
        src/actions/PlayAudioActions.cpp
        src/actions/NotifyGUIAction.cpp
        src/actions/NotifyGUIBedtimeReminderAction.cpp
        src/actions/FrontlightAction.cpp

        include/AbstractAlarmAction.hpp


@@ 14,10 15,12 @@ target_sources(alarms
        src/actions/PlayAudioActions.hpp
        src/actions/FrontlightAction.hpp
        src/actions/NotifyGUIAction.hpp
        src/actions/NotifyGUIBedtimeReminderAction.hpp
    PUBLIC
        include/AlarmSoundPaths.hpp
        include/popups/AlarmActivatedPopupRequestParams.hpp
        include/popups/AlarmDeactivatedPopupRequestParams.hpp
        include/popups/BedtimeReminderPopupRequestParams.hpp
)

target_include_directories(alarms


@@ 33,6 36,7 @@ target_link_libraries(alarms
        module-audio
        module-vfs
        bell::db
        bell::appmgr
        bell::app-common
        apps-common
   PUBLIC

M products/BellHybrid/alarms/include/AlarmSoundPaths.hpp => products/BellHybrid/alarms/include/AlarmSoundPaths.hpp +1 -0
@@ 11,4 11,5 @@ namespace alarms::paths
    std::filesystem::path getMusicDir() noexcept;
    std::filesystem::path getPreWakeUpChimesDir() noexcept;
    std::filesystem::path getSnoozeChimesDir() noexcept;
    std::filesystem::path getBedtimeReminderChimesDir() noexcept;
} // namespace alarms::paths

M products/BellHybrid/alarms/include/BellAlarmHandler.hpp => products/BellHybrid/alarms/include/BellAlarmHandler.hpp +8 -0
@@ 49,4 49,12 @@ namespace alarms
      private:
        static auto getActions(sys::Service *service) -> Actions;
    };
    class BedtimeReminderHandler : public BellAlarmHandler
    {
      public:
        explicit BedtimeReminderHandler(sys::Service *service);

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

A products/BellHybrid/alarms/include/popups/BedtimeReminderPopupRequestParams.hpp => products/BellHybrid/alarms/include/popups/BedtimeReminderPopupRequestParams.hpp +16 -0
@@ 0,0 1,16 @@
// 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 <apps-common/popups/data/PopupRequestParams.hpp>

namespace gui
{
    class BedtimeReminderPopupRequestParams : public PopupRequestParams
    {
      public:
        BedtimeReminderPopupRequestParams() : PopupRequestParams{gui::popup::ID::BedtimeNotification}
        {}
    };
} // namespace gui

M products/BellHybrid/alarms/src/AlarmSoundPaths.cpp => products/BellHybrid/alarms/src/AlarmSoundPaths.cpp +6 -0
@@ 21,8 21,14 @@ namespace alarms::paths
    {
        return purefs::dir::getCurrentOSPath() / "assets/audio/bell/prewakeup";
    }

    std::filesystem::path getSnoozeChimesDir() noexcept
    {
        return purefs::dir::getCurrentOSPath() / "assets/audio/bell/chimes";
    }

    std::filesystem::path getBedtimeReminderChimesDir() noexcept
    {
        return purefs::dir::getCurrentOSPath() / "assets/audio/bell/evening_reminder";
    }
} // namespace alarms::paths

A products/BellHybrid/alarms/src/actions/NotifyGUIBedtimeReminderAction.cpp => products/BellHybrid/alarms/src/actions/NotifyGUIBedtimeReminderAction.cpp +21 -0
@@ 0,0 1,21 @@
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include "NotifyGUIBedtimeReminderAction.hpp"

#include <service-appmgr/include/service-appmgr/Constants.hpp>
#include <appmgr/messages/AlarmMessage.hpp>

namespace alarms
{
    NotifyGUIBedtimeReminderAction::NotifyGUIBedtimeReminderAction(sys::Service &service) : service{service}
    {}
    bool NotifyGUIBedtimeReminderAction::execute()
    {
        return service.bus.sendUnicast(std::make_shared<BedtimeNotification>(), service::name::appmgr);
    }
    bool NotifyGUIBedtimeReminderAction::turnOff()
    {
        return true;
    }
} // namespace alarms

A products/BellHybrid/alarms/src/actions/NotifyGUIBedtimeReminderAction.hpp => products/BellHybrid/alarms/src/actions/NotifyGUIBedtimeReminderAction.hpp +23 -0
@@ 0,0 1,23 @@
// 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 "AbstractAlarmAction.hpp"

#include <Service/Service.hpp>

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

      private:
        sys::Service &service;
    };

} // namespace alarms

M products/BellHybrid/alarms/src/actions/PlayAudioActions.cpp => products/BellHybrid/alarms/src/actions/PlayAudioActions.cpp +10 -0
@@ 65,6 65,11 @@ namespace alarms
        return play(tonePath, ringingDuration);
    }

    bool PlayBedtimeToneAction::execute()
    {
        return play(paths::getBedtimeReminderChimesDir() / bedtimeNotificationAudoFile, InfiniteDuration);
    }

    std::unique_ptr<PlayChimeAction> createPreWakeUpChimeAction(sys::Service &service)
    {
        return std::make_unique<PlayChimeAction>(


@@ 76,6 81,11 @@ namespace alarms
        return std::make_unique<PlayChimeAction>(service, paths::getSnoozeChimesDir(), bell::settings::Snooze::tone);
    }

    std::unique_ptr<PlayBedtimeToneAction> createBedtimeChimeAction(sys::Service &service)
    {
        return std::make_unique<PlayBedtimeToneAction>(service);
    }

    PlayChimeAction::PlayChimeAction(sys::Service &service,
                                     const std::filesystem::path &tonesDirPath,
                                     std::string_view toneSetting)

M products/BellHybrid/alarms/src/actions/PlayAudioActions.hpp => products/BellHybrid/alarms/src/actions/PlayAudioActions.hpp +11 -0
@@ 45,6 45,15 @@ namespace alarms
        settings::Settings settings;
    };

    class PlayBedtimeToneAction : public PlayToneAction
    {
        static auto constexpr bedtimeNotificationAudoFile = "Evening_Horizon.mp3";

      public:
        using PlayToneAction::PlayToneAction;
        bool execute() override;
    };

    class PlayChimeAction : public PlayAudioAction
    {
      public:


@@ 61,4 70,6 @@ namespace alarms

    std::unique_ptr<PlayChimeAction> createPreWakeUpChimeAction(sys::Service &service);
    std::unique_ptr<PlayChimeAction> createSnoozeChimeAction(sys::Service &service);
    std::unique_ptr<PlayBedtimeToneAction> createBedtimeChimeAction(sys::Service &service);

} // namespace alarms

M products/BellHybrid/apps/Application.cpp => products/BellHybrid/apps/Application.cpp +8 -0
@@ 15,6 15,7 @@
#include <common/windows/BellTurnOffWindow.hpp>
#include <common/windows/BellWelcomeWindow.hpp>
#include <service-appmgr/Constants.hpp>
#include <common/popups/BedtimeNotificationWindow.hpp>

namespace app
{


@@ 58,6 59,13 @@ namespace app
                    return std::make_unique<gui::BellRebootWindow>(app,
                                                                   std::make_unique<gui::BellPowerOffPresenter>(app));
                });
                break;
            case ID::BedtimeNotification:
                windowsFactory.attach(window::bedtime_notification_window,
                                      [](app::ApplicationCommon *app, const std::string &name) {
                                          return std::make_unique<gui::BedtimeNotificationWindow>(app);
                                      });
                break;
            default:
                break;
            }

M products/BellHybrid/apps/CMakeLists.txt => products/BellHybrid/apps/CMakeLists.txt +1 -0
@@ 24,6 24,7 @@ add_subdirectory(application-bell-main)
add_subdirectory(application-bell-onboarding)
add_subdirectory(application-bell-background-sounds)
add_subdirectory(application-bell-alarm)
add_subdirectory(application-bell-bedtime)
add_subdirectory(application-bell-settings)
add_subdirectory(application-bell-powernap)
add_subdirectory(common)

M products/BellHybrid/apps/application-bell-alarm/ApplicationBellAlarm.cpp => products/BellHybrid/apps/application-bell-alarm/ApplicationBellAlarm.cpp +2 -1
@@ 65,7 65,8 @@ namespace app
        attachPopups({gui::popup::ID::AlarmActivated,
                      gui::popup::ID::AlarmDeactivated,
                      gui::popup::ID::PowerOff,
                      gui::popup::ID::Reboot});
                      gui::popup::ID::Reboot,
                      gui::popup::ID::BedtimeNotification});
    }

    sys::MessagePointer ApplicationBellAlarm::DataReceivedHandler(sys::DataMessage *msgl, sys::ResponseMessage *resp)

M products/BellHybrid/apps/application-bell-background-sounds/ApplicationBellBackgroundSounds.cpp => products/BellHybrid/apps/application-bell-background-sounds/ApplicationBellBackgroundSounds.cpp +2 -1
@@ 77,7 77,8 @@ namespace app
        attachPopups({gui::popup::ID::AlarmActivated,
                      gui::popup::ID::AlarmDeactivated,
                      gui::popup::ID::PowerOff,
                      gui::popup::ID::Reboot});
                      gui::popup::ID::Reboot,
                      gui::popup::ID::BedtimeNotification});
    }

    sys::MessagePointer ApplicationBellBackgroundSounds::DataReceivedHandler(sys::DataMessage *msgl,

A products/BellHybrid/apps/application-bell-bedtime/ApplicationBellBedtime.cpp => products/BellHybrid/apps/application-bell-bedtime/ApplicationBellBedtime.cpp +60 -0
@@ 0,0 1,60 @@
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include "ApplicationBellBedtime.hpp"
#include "presenter/BellBedtimeWindowPresenter.hpp"
#include "windows/BellBedtimeWindow.hpp"
#include "common/models/BedtimeModel.hpp"
#include "models/BedtimeListItemProvider.hpp"

#include <common/windows/BellFinishedCallbackWindow.hpp>
namespace app
{
    ApplicationBellBedtime::ApplicationBellBedtime(std::string name,
                                                   std::string parent,
                                                   StatusIndicators statusIndicators,
                                                   StartInBackground startInBackground)
        : Application(name, parent, statusIndicators, startInBackground)
    {}

    sys::ReturnCodes ApplicationBellBedtime::InitHandler()
    {
        auto ret = Application::InitHandler();
        if (ret != sys::ReturnCodes::Success) {
            return ret;
        }

        createUserInterface();

        return sys::ReturnCodes::Success;
    }

    void ApplicationBellBedtime::createUserInterface()
    {
        windowsFactory.attach(gui::name::window::main_window, [this](ApplicationCommon *app, const std::string &) {
            auto bedtimeModel = std::make_unique<bell_bedtime::BedtimeModel>(app);
            auto provider     = std::make_shared<bell_bedtime::BedtimeListItemProvider>(std::move(bedtimeModel));
            auto presenter    = std::make_unique<bell_bedtime::BellBedtimeWindowPresenter>(provider);
            return std::make_unique<gui::BellBedtimeWindow>(app, std::move(presenter));
        });

        windowsFactory.attach(gui::BellFinishedCallbackWindow::defaultName,
                              [](ApplicationCommon *app, const std::string &name) {
                                  return std::make_unique<gui::BellFinishedCallbackWindow>(app);
                              });

        attachPopups({gui::popup::ID::AlarmActivated,
                      gui::popup::ID::AlarmDeactivated,
                      gui::popup::ID::PowerOff,
                      gui::popup::ID::Reboot});
    }

    sys::MessagePointer ApplicationBellBedtime::DataReceivedHandler(sys::DataMessage *msgl, sys::ResponseMessage *resp)
    {
        auto retMsg = Application::DataReceivedHandler(msgl);
        if (dynamic_cast<sys::ResponseMessage *>(retMsg.get())->retCode == sys::ReturnCodes::Success) {
            return retMsg;
        }
        return handleAsyncResponse(resp);
    }
} // namespace app

A products/BellHybrid/apps/application-bell-bedtime/CMakeLists.txt => products/BellHybrid/apps/application-bell-bedtime/CMakeLists.txt +38 -0
@@ 0,0 1,38 @@
add_library(application-bell-bedtime)
add_library(bell::app-bedtime ALIAS application-bell-bedtime)

target_sources(application-bell-bedtime
    PRIVATE
        ApplicationBellBedtime.cpp
        models/BedtimeListItemProvider.cpp
        presenter/BellBedtimeWindowPresenter.cpp
        windows/BellBedtimeWindow.cpp
    PRIVATE
        data/BellBedtimeStyle.hpp
        models/BedtimeListItemProvider.hpp
        presenter/BellBedtimeWindowPresenter.hpp
        windows/BellBedtimeWindow.hpp
    PUBLIC
        include/application-bell-bedtime/ApplicationBellBedtime.hpp
)

target_include_directories(application-bell-bedtime
    PRIVATE
        $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
        $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include/application-bell-bedtime>
    PUBLIC
        $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
)

target_link_libraries(application-bell-bedtime
    PRIVATE
        app
        bellgui
        bell::app-common
        bell::db
        date::date
        service-appmgr
    PUBLIC
        module-gui
        bell::app-common
)

A products/BellHybrid/apps/application-bell-bedtime/data/BellBedtimeStyle.hpp => products/BellHybrid/apps/application-bell-bedtime/data/BellBedtimeStyle.hpp +21 -0
@@ 0,0 1,21 @@
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#pragma once

namespace gui
{
    namespace bell_bedtime_style
    {
        namespace time_set_fmt_spinner
        {
            inline constexpr auto focusFont   = style::window::font::supersizeme;
            inline constexpr auto noFocusFont = style::window::font::supersizemelight;
        } // namespace time_set_fmt_spinner

        namespace top_text
        {
            inline constexpr auto font = style::window::font::largelight;
        }
    } // namespace bell_bedtime_style
} // namespace gui

A products/BellHybrid/apps/application-bell-bedtime/include/application-bell-bedtime/ApplicationBellBedtime.hpp => products/BellHybrid/apps/application-bell-bedtime/include/application-bell-bedtime/ApplicationBellBedtime.hpp +48 -0
@@ 0,0 1,48 @@
// 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 <Application.hpp>

namespace gui::window::name
{
    inline constexpr auto bellBedtime      = "BellBedtime";
    inline constexpr auto bellBedtimeOnOff = "bellBedtimeOnff";

} // namespace gui::window::name

namespace app
{
    inline constexpr auto applicationBellBedtimeName = "ApplicationBellBedtime";

    class ApplicationBellBedtime : public Application
    {
      public:
        explicit ApplicationBellBedtime(std::string name                    = applicationBellBedtimeName,
                                        std::string parent                  = "",
                                        StatusIndicators statusIndicators   = StatusIndicators{},
                                        StartInBackground startInBackground = {false});

        auto InitHandler() -> sys::ReturnCodes override;

        void createUserInterface() override;
        void destroyUserInterface() override
        {}

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

        auto SwitchPowerModeHandler(const sys::ServicePowerMode mode) -> sys::ReturnCodes override final
        {
            return sys::ReturnCodes::Success;
        }
    };

    template <> struct ManifestTraits<ApplicationBellBedtime>
    {
        static auto GetManifest() -> manager::ApplicationManifest
        {
            return {{manager::actions::Launch}};
        }
    };
} // namespace app

A products/BellHybrid/apps/application-bell-bedtime/models/BedtimeListItemProvider.cpp => products/BellHybrid/apps/application-bell-bedtime/models/BedtimeListItemProvider.cpp +71 -0
@@ 0,0 1,71 @@
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include "BedtimeListItemProvider.hpp"
#include "common/widgets/ListItems.hpp"
#include "data/BellBedtimeStyle.hpp"

#include <apps-common/ApplicationCommon.hpp>
#include <gui/widgets/ListViewEngine.hpp>
#include <service-time/api/TimeSettingsApi.hpp>

namespace app::bell_bedtime
{
    using namespace gui;

    BedtimeListItemProvider::BedtimeListItemProvider(std::unique_ptr<AbstractBedtimeModel> &&model)
        : model{std::move(model)}
    {
        buildListItems();
    }

    void BedtimeListItemProvider::buildListItems()
    {
        constexpr auto itemCount = 2U;
        internalData.reserve(itemCount);

        auto onOff       = new OnOffListItem(model.get()->getBedtimeOnOff(), utils::translate("app_bellmain_bedtime"));
        onOff->onProceed = [onOff, this]() {
            if (not onOff->isActive()) {
                this->onExit(false);
            }
        };
        internalData.emplace_back(onOff);
        internalData.emplace_back(new TimeListItem(model.get()->getBedtimeTime(),
                                                   stm::api::timeFormat(),
                                                   bell_bedtime_style::time_set_fmt_spinner::focusFont,
                                                   bell_bedtime_style::time_set_fmt_spinner::noFocusFont,
                                                   utils::translate("app_bellmain_bedtime")));

        for (auto item : internalData) {
            item->deleteByList = false;
        }
    }

    auto BedtimeListItemProvider::requestRecords(uint32_t offset, uint32_t limit) -> void
    {
        setupModel(offset, limit);
        list->onProviderDataUpdate();
    }

    auto BedtimeListItemProvider::getItem(Order order) -> ListItem *
    {
        return getRecord(order);
    }

    auto BedtimeListItemProvider::requestRecordsCount() -> unsigned int
    {
        return internalData.size();
    }

    auto BedtimeListItemProvider::getMinimalItemSpaceRequired() const -> unsigned int
    {
        return style::sidelistview::list_item::w;
    }

    auto BedtimeListItemProvider::getListItems() -> std::vector<BellSideListItemWithCallbacks *>
    {
        return internalData;
    }

} // namespace app::bell_bedtime

A products/BellHybrid/apps/application-bell-bedtime/models/BedtimeListItemProvider.hpp => products/BellHybrid/apps/application-bell-bedtime/models/BedtimeListItemProvider.hpp +31 -0
@@ 0,0 1,31 @@
// 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/models/AbstractBedtimeModel.hpp>
#include <common/widgets/BellSideListItemWithCallbacks.hpp>
#include <apps-common/InternalModel.hpp>

namespace app::bell_bedtime
{
    class BedtimeListItemProvider : public app::InternalModel<gui::BellSideListItemWithCallbacks *>,
                                    public gui::ListItemProvider
    {
      public:
        explicit BedtimeListItemProvider(std::unique_ptr<AbstractBedtimeModel> &&model);
        auto getListItems() -> std::vector<gui::BellSideListItemWithCallbacks *>;
        auto requestRecords(uint32_t offset, uint32_t limit) -> void override;
        [[nodiscard]] auto getItem(gui::Order order) -> gui::ListItem * override;
        [[nodiscard]] auto requestRecordsCount() -> unsigned int override;
        [[nodiscard]] auto getMinimalItemSpaceRequired() const -> unsigned int override;

        std::function<void(bool)> onExit;

      private:
        void buildListItems();

        std::unique_ptr<AbstractBedtimeModel> model;
    };

} // namespace app::bell_bedtime

A products/BellHybrid/apps/application-bell-bedtime/presenter/BellBedtimeWindowPresenter.cpp => products/BellHybrid/apps/application-bell-bedtime/presenter/BellBedtimeWindowPresenter.cpp +33 -0
@@ 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

#include "BellBedtimeWindowPresenter.hpp"
#include "models/BedtimeListItemProvider.hpp"

namespace app::bell_bedtime
{
    BellBedtimeWindowPresenter::BellBedtimeWindowPresenter(std::shared_ptr<BedtimeListItemProvider> provider)
        : provider{provider}
    {
        provider->onExit = [this](bool showSuccessWindow) { getView()->exit(showSuccessWindow); };
    }

    void BellBedtimeWindowPresenter::saveData()
    {
        for (const auto &item : provider->getListItems()) {
            item->getValue();
        }
    }

    void BellBedtimeWindowPresenter::loadData()
    {
        for (const auto &item : provider->getListItems()) {
            item->setValue();
        }
    }

    auto BellBedtimeWindowPresenter::getPagesProvider() const -> std::shared_ptr<gui::ListItemProvider>
    {
        return provider;
    }
} // namespace app::bell_bedtime

A products/BellHybrid/apps/application-bell-bedtime/presenter/BellBedtimeWindowPresenter.hpp => products/BellHybrid/apps/application-bell-bedtime/presenter/BellBedtimeWindowPresenter.hpp +58 -0
@@ 0,0 1,58 @@
// 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 <apps-common/BasePresenter.hpp>
#include "common/models/AbstractBedtimeModel.hpp"

namespace app
{
    class ApplicationCommon;
}

namespace settings
{
    class Settings;
}

namespace gui
{
    class AppWindow;
    class ListItemProvider;
} // namespace gui

namespace app::bell_bedtime
{
    class BedtimeListItemProvider;

    class View
    {
      public:
        virtual ~View() noexcept                  = default;
        virtual void exit(bool showSuccessWindow) = 0;
    };

    class AbstractBedtimePresenter : public BasePresenter<View>
    {
      public:
        virtual ~AbstractBedtimePresenter() noexcept                                    = default;
        virtual auto getPagesProvider() const -> std::shared_ptr<gui::ListItemProvider> = 0;
        virtual void saveData()                                                         = 0;
        virtual void loadData()                                                         = 0;
    };

    class BellBedtimeWindowPresenter : public AbstractBedtimePresenter
    {
      private:
        std::shared_ptr<BedtimeListItemProvider> provider;
        std::unique_ptr<AbstractBedtimeModel> settings;

      public:
        explicit BellBedtimeWindowPresenter(std::shared_ptr<BedtimeListItemProvider> provider);
        auto getPagesProvider() const -> std::shared_ptr<gui::ListItemProvider> override;
        void saveData() override;
        void loadData() override;
    };
} // namespace app::bell_bedtime

A products/BellHybrid/apps/application-bell-bedtime/windows/BellBedtimeWindow.cpp => products/BellHybrid/apps/application-bell-bedtime/windows/BellBedtimeWindow.cpp +83 -0
@@ 0,0 1,83 @@
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include "BellBedtimeWindow.hpp"

#include <apps-common/widgets/BellBaseLayout.hpp>
#include <apps-common/widgets/TimeSetFmtSpinner.hpp>

#include <data/BellBedtimeStyle.hpp>
#include <module-gui/gui/input/InputEvent.hpp>

#include <module-gui/gui/widgets/TextFixedSize.hpp>
#include <module-gui/gui/widgets/ThreeBox.hpp>
#include <module-gui/gui/widgets/Image.hpp>

#include <widgets/SideListView.hpp>
#include <common/windows/BellFinishedCallbackWindow.hpp>
#include "service-appmgr/Controller.hpp" // for Controller

namespace gui
{
    BellBedtimeWindow::BellBedtimeWindow(
        app::ApplicationCommon *app,
        std::unique_ptr<app::bell_bedtime::BellBedtimeWindowPresenter> &&windowPresenter,
        std::string name)
        : AppWindow(app, std::move(name)), presenter{std::move(windowPresenter)}
    {
        presenter->attach(this);
        buildInterface();
    }

    void BellBedtimeWindow::buildInterface()
    {
        AppWindow::buildInterface();

        statusBar->setVisible(false);
        header->setTitleVisibility(true);
        bottomBar->setVisible(false);

        listView = new SideListView(
            this, 0U, 0U, this->getWidth(), this->getHeight(), presenter->getPagesProvider(), PageBarType::None);
        listView->setEdges(RectangleEdge::None);

        listView->rebuildList(listview::RebuildType::Full);

        presenter->loadData();

        setFocusItem(listView);
    }

    bool BellBedtimeWindow::onInput(const InputEvent &inputEvent)
    {
        if (listView->onInput(inputEvent)) {
            return true;
        }
        if (inputEvent.isShortRelease(KeyCode::KEY_ENTER)) {
            exit(true);
            return true;
        }
        return AppWindow::onInput(inputEvent);
    }

    void BellBedtimeWindow::rebuild()
    {
        erase();
        buildInterface();
    }

    void BellBedtimeWindow::exit(bool showSuccessWindow)
    {
        presenter->saveData();
        if (showSuccessWindow) {
            application->switchWindow(BellFinishedCallbackWindow::defaultName,
                                      BellFinishedCallbackWindowSwitchData::Factory::create(
                                          "circle_success",
                                          utils::translate("app_bell_bedtime_set_finished"),
                                          [this]() { app::manager::Controller::switchBack(application); }));
        }
        else {
            application->returnToPreviousWindow();
        }
    }
} /* namespace gui */

A products/BellHybrid/apps/application-bell-bedtime/windows/BellBedtimeWindow.hpp => products/BellHybrid/apps/application-bell-bedtime/windows/BellBedtimeWindow.hpp +31 -0
@@ 0,0 1,31 @@
// 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 "ApplicationBellBedtime.hpp"
#include "presenter/BellBedtimeWindowPresenter.hpp"

#include <apps-common/windows/AppWindow.hpp>

namespace gui
{
    class SideListView;

    class BellBedtimeWindow : public AppWindow, public app::bell_bedtime::View
    {
      public:
        BellBedtimeWindow(app::ApplicationCommon *app,
                          std::unique_ptr<app::bell_bedtime::BellBedtimeWindowPresenter> &&windowPresenter,
                          std::string name = window::name::bellBedtime);

        void buildInterface() override;
        auto onInput(const InputEvent &inputEvent) -> bool override;
        void rebuild() override;
        void exit(bool showSuccessWindow) override;

      private:
        SideListView *listView{};
        std::unique_ptr<app::bell_bedtime::BellBedtimeWindowPresenter> presenter;
    };
} /* namespace gui */

M products/BellHybrid/apps/application-bell-main/ApplicationBellMain.cpp => products/BellHybrid/apps/application-bell-main/ApplicationBellMain.cpp +4 -1
@@ 15,6 15,8 @@
#include <common/models/TimeModel.hpp>
#include <service-db/DBNotificationMessage.hpp>
#include <windows/Dialog.hpp>
#include <service-audio/AudioMessage.hpp>
#include <common/popups/BedtimeNotificationWindow.hpp>

namespace app
{


@@ 72,7 74,8 @@ namespace app
        attachPopups({gui::popup::ID::AlarmActivated,
                      gui::popup::ID::AlarmDeactivated,
                      gui::popup::ID::PowerOff,
                      gui::popup::ID::Reboot});
                      gui::popup::ID::Reboot,
                      gui::popup::ID::BedtimeNotification});
    }

    sys::MessagePointer ApplicationBellMain::DataReceivedHandler(sys::DataMessage *msgl, sys::ResponseMessage *resp)

M products/BellHybrid/apps/application-bell-main/CMakeLists.txt => products/BellHybrid/apps/application-bell-main/CMakeLists.txt +1 -0
@@ 53,6 53,7 @@ target_link_libraries(application-bell-main
        bell::app-alarm
        bell::app-onboarding
        bell::app-background-sounds
        bell::app-bedtime
        bell::app-settings
        bell::app-powernap
        bell::keymap

M products/BellHybrid/apps/application-bell-main/include/application-bell-main/ApplicationBellMain.hpp => products/BellHybrid/apps/application-bell-main/include/application-bell-main/ApplicationBellMain.hpp +1 -0
@@ 4,6 4,7 @@
#pragma once

#include <Application.hpp>
#include <common/models/BedtimeModel.hpp>

namespace gui::window::name
{

M products/BellHybrid/apps/application-bell-main/windows/BellMainMenuWindow.cpp => products/BellHybrid/apps/application-bell-main/windows/BellMainMenuWindow.cpp +2 -1
@@ 5,6 5,7 @@

#include <application-bell-alarm/ApplicationBellAlarm.hpp>
#include <application-bell-background-sounds/ApplicationBellBackgroundSounds.hpp>
#include <application-bell-bedtime/ApplicationBellBedtime.hpp>
#include <application-bell-main/ApplicationBellMain.hpp>
#include <application-bell-settings/ApplicationBellSettings.hpp>
#include <application-bell-powernap/ApplicationBellPowerNap.hpp>


@@ 70,7 71,7 @@ namespace gui
        addAppMenu(utils::translate("app_bellmain_background_sounds"), app::applicationBellBackgroundSoundsName);
        // for demo only - to be replaced by call o final window
        addWinMenu(utils::translate("app_bellmain_meditation_timer"), gui::window::name::bell_main_menu_dialog);
        addWinMenu(utils::translate("app_bellmain_bedtime"), gui::window::name::bell_main_menu_dialog);
        addAppMenu(utils::translate("app_bellmain_bedtime"), app::applicationBellBedtimeName);

        addAppMenu(utils::translate("app_bellmain_settings"), app::applicationBellSettingsName);


M products/BellHybrid/apps/application-bell-powernap/ApplicationBellPowerNap.cpp => products/BellHybrid/apps/application-bell-powernap/ApplicationBellPowerNap.cpp +2 -1
@@ 56,7 56,8 @@ namespace app
        attachPopups({gui::popup::ID::AlarmActivated,
                      gui::popup::ID::AlarmDeactivated,
                      gui::popup::ID::PowerOff,
                      gui::popup::ID::Reboot});
                      gui::popup::ID::Reboot,
                      gui::popup::ID::BedtimeNotification});
    }

    sys::MessagePointer ApplicationBellPowerNap::DataReceivedHandler(sys::DataMessage *msgl, sys::ResponseMessage *resp)

M products/BellHybrid/apps/application-bell-settings/ApplicationBellSettings.cpp => products/BellHybrid/apps/application-bell-settings/ApplicationBellSettings.cpp +2 -1
@@ 205,7 205,8 @@ namespace app
        attachPopups({gui::popup::ID::AlarmActivated,
                      gui::popup::ID::AlarmDeactivated,
                      gui::popup::ID::PowerOff,
                      gui::popup::ID::Reboot});
                      gui::popup::ID::Reboot,
                      gui::popup::ID::BedtimeNotification});
    }

    sys::MessagePointer ApplicationBellSettings::DataReceivedHandler(sys::DataMessage *msgl, sys::ResponseMessage *resp)

M products/BellHybrid/apps/application-bell-settings/CMakeLists.txt => products/BellHybrid/apps/application-bell-settings/CMakeLists.txt +0 -2
@@ 23,7 23,6 @@ target_sources(application-bell-settings
    PRIVATE
        ApplicationBellSettings.cpp
        models/FrontlightModel.cpp
        models/SettingsModel.cpp
        models/TemperatureUnitModel.cpp
        models/TimeUnitsModel.cpp
        models/advanced/AboutYourBellModel.cpp


@@ 61,7 60,6 @@ target_sources(application-bell-settings
        windows/alarm_settings/BellSettingsAlarmSettingsWindow.cpp
        windows/alarm_settings/BellSettingsPrewakeUpWindow.cpp

        models/SettingsModel.hpp
        models/advanced/AboutYourBellModel.hpp
        models/alarm_settings/AbstractAlarmSettingsModel.hpp
        models/alarm_settings/AbstractPrewakeUpSettingsModel.hpp

M products/BellHybrid/apps/application-bell-settings/data/BellSettingsStyle.hpp => products/BellHybrid/apps/application-bell-settings/data/BellSettingsStyle.hpp +10 -0
@@ 49,5 49,15 @@ namespace gui
                inline constexpr auto value_height = 33;
            } // namespace list_item
        }     // namespace about_your_bell_window
        namespace bedtime_settings_window
        {
            inline constexpr auto options_list_margin_x = 100U;
            inline constexpr auto options_list_margin_y = 110U;
            inline constexpr auto default_body_width    = 400U;
        } // namespace bedtime_settings_window
        namespace bedtime_settings_chime_tone
        {
            inline constexpr auto font_center = "gt_pressura_light_46";
        }
    } // namespace bell_settings_style
} // namespace gui

M products/BellHybrid/apps/application-bell-settings/models/alarm_settings/AlarmSettingsModel.hpp => products/BellHybrid/apps/application-bell-settings/models/alarm_settings/AlarmSettingsModel.hpp +1 -1
@@ 4,7 4,7 @@
#pragma once

#include "AbstractAlarmSettingsModel.hpp"
#include <models/SettingsModel.hpp>
#include <common/models/SettingsModel.hpp>

namespace app::bell_settings
{

M products/BellHybrid/apps/application-bell-settings/models/alarm_settings/PrewakeUpSettingsModel.hpp => products/BellHybrid/apps/application-bell-settings/models/alarm_settings/PrewakeUpSettingsModel.hpp +1 -1
@@ 4,7 4,7 @@
#pragma once

#include "AbstractPrewakeUpSettingsModel.hpp"
#include <models/SettingsModel.hpp>
#include <common/models/SettingsModel.hpp>

namespace app::bell_settings
{

M products/BellHybrid/apps/application-bell-settings/models/alarm_settings/SnoozeSettingsModel.hpp => products/BellHybrid/apps/application-bell-settings/models/alarm_settings/SnoozeSettingsModel.hpp +1 -1
@@ 4,7 4,7 @@
#pragma once

#include "AbstractSnoozeSettingsModel.hpp"
#include <models/SettingsModel.hpp>
#include <common/models/SettingsModel.hpp>

namespace app::bell_settings
{

M products/BellHybrid/apps/common/CMakeLists.txt => products/BellHybrid/apps/common/CMakeLists.txt +13 -1
@@ 16,15 16,21 @@ target_sources(application-bell-common
        src/TimeModel.cpp
        src/SoundsRepository.cpp
        src/windows/BellFinishedWindow.cpp
        src/windows/BellFinishedCallbackWindow.cpp
        src/windows/BellTurnOffWindow.cpp
        src/windows/BellWelcomeWindow.cpp
        src/BellSideListItemWithCallbacks.cpp
        src/TimeUtils.cpp
        src/popups/presenter/AlarmActivatedPresenter.cpp
        src/TimeUtils.cpp
        src/models/SettingsModel.cpp
        src/models/BedtimeModel.cpp
        src/popups/AlarmActivatedWindow.cpp
        src/popups/AlarmActivatedWindow.cpp
        src/popups/BedtimeNotificationWindow.cpp
        src/popups/AlarmDeactivatedWindow.cpp
        src/popups/BellTurnOffOptionWindow.cpp
        src/popups/BellRebootWindow.cpp
        src/popups/presenter/AlarmActivatedPresenter.cpp
        src/widgets/ListItems.cpp
        src/widgets/BellStatusClock.cpp



@@ 35,18 41,24 @@ target_sources(application-bell-common
        include/common/SoundsRepository.hpp
        include/common/BellPowerOffPresenter.hpp
        include/common/windows/BellFinishedWindow.hpp
        include/common/windows/BellFinishedCallbackWindow.hpp
        include/common/windows/BellTurnOffWindow.hpp
        include/common/windows/BellWelcomeWindow.hpp
        include/common/TimeUtils.hpp
        include/common/data/BellFinishedCallbackWindowSwitchData.hpp
        include/common/models/AbstractAlarmModel.hpp
        include/common/models/AbstractBedtimeModel.hpp
        include/common/models/AbstractSettingsModel.hpp
        include/common/models/AbstractAudioModel.hpp
        include/common/models/AlarmModel.hpp
        include/common/models/SettingsModel.hpp
        include/common/models/BedtimeModel.hpp
        include/common/models/TimeModel.hpp
        include/common/models/AudioModel.hpp
        include/common/popups/presenter/AlarmActivatedPresenter.hpp
        include/common/popups/AlarmActivatedWindow.hpp
        include/common/popups/AlarmDeactivatedWindow.hpp
        include/common/popups/BedtimeNotificationWindow.hpp
        include/common/popups/BellTurnOffOptionWindow.hpp
        include/common/popups/BellRebootWindow.hpp
        include/common/widgets/BellSideListItemWithCallbacks.hpp

A products/BellHybrid/apps/common/include/common/data/BellFinishedCallbackWindowSwitchData.hpp => products/BellHybrid/apps/common/include/common/data/BellFinishedCallbackWindowSwitchData.hpp +37 -0
@@ 0,0 1,37 @@
// 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 <functional> // for function
#include <SwitchData.hpp>
#include <utf8/UTF8.hpp>

namespace gui
{
    struct BellFinishedCallbackWindowSwitchData : public gui::SwitchData
    {
      public:
        struct Factory
        {
            static std::unique_ptr<BellFinishedCallbackWindowSwitchData> create(const UTF8 &icon,
                                                                                const UTF8 &text,
                                                                                std::function<void()> finishCallback)
            {
                return std::unique_ptr<BellFinishedCallbackWindowSwitchData>(
                    new BellFinishedCallbackWindowSwitchData(icon, text, finishCallback));
            }
        };

        UTF8 icon{};
        UTF8 text{};
        std::function<void()> finishCallback;

      private:
        BellFinishedCallbackWindowSwitchData() = default;

        BellFinishedCallbackWindowSwitchData(const UTF8 &icon, const UTF8 &text, std::function<void()> finishCallback)
            : icon{icon}, text{text}, finishCallback{finishCallback}
        {}
    };
} // namespace gui

A products/BellHybrid/apps/common/include/common/models/AbstractBedtimeModel.hpp => products/BellHybrid/apps/common/include/common/models/AbstractBedtimeModel.hpp +18 -0
@@ 0,0 1,18 @@
// 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/models/AbstractSettingsModel.hpp"
#include <time.h>

namespace app
{
    class AbstractBedtimeModel
    {
      public:
        virtual ~AbstractBedtimeModel()                                       = default;
        virtual auto getBedtimeOnOff() -> gui::AbstractSettingsModel<bool> &  = 0;
        virtual auto getBedtimeTime() -> gui::AbstractSettingsModel<time_t> & = 0;
    };
} // namespace app

A products/BellHybrid/apps/common/include/common/models/BedtimeModel.hpp => products/BellHybrid/apps/common/include/common/models/BedtimeModel.hpp +59 -0
@@ 0,0 1,59 @@
// 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 "AbstractBedtimeModel.hpp"
#include "SettingsModel.hpp"
#include <Service/Service.hpp>
#include <ctime>

namespace app::bell_bedtime
{
    inline constexpr auto DEFAULT_BEDTIME_TIME = "21:00";
    class BedtimeOnOffModel : public gui::SettingsModel<bool>
    {
      public:
        using SettingsModel::SettingsModel;

        void setValue(bool value) override;
        auto getValue() const -> bool override;
    };

    class BedtimeTimeModel : public gui::SettingsModel<time_t>
    {
        auto writeString(std::string str) -> void;
        auto readString() const -> std::string;
        auto getTmFromString(const std::string &str, std::tm &tm) const -> bool;

      public:
        using SettingsModel::SettingsModel;

        void setValue(time_t value) override;
        auto getValue() const -> time_t override;
    };

    class BedtimeModel : public AbstractBedtimeModel
    {
      public:
        BedtimeModel() = delete;

        explicit BedtimeModel(sys::Service *app)
        {
            bedtimeOnOff = std::make_unique<bell_bedtime::BedtimeOnOffModel>(app);
            bedtimeTime  = std::make_unique<bell_bedtime::BedtimeTimeModel>(app);
        }
        gui::AbstractSettingsModel<bool> &getBedtimeOnOff() override
        {
            return *bedtimeOnOff;
        }
        gui::AbstractSettingsModel<time_t> &getBedtimeTime() override
        {
            return *bedtimeTime;
        }

      private:
        std::unique_ptr<gui::AbstractSettingsModel<bool>> bedtimeOnOff;
        std::unique_ptr<gui::AbstractSettingsModel<time_t>> bedtimeTime;
    };
} // namespace app::bell_bedtime

R products/BellHybrid/apps/application-bell-settings/models/SettingsModel.hpp => products/BellHybrid/apps/common/include/common/models/SettingsModel.hpp +2 -1
@@ 6,6 6,7 @@
#include <common/models/AbstractSettingsModel.hpp>

#include <service-db/Settings.hpp>
#include <Service/Service.hpp>

namespace app
{


@@ 17,7 18,7 @@ namespace gui
    template <class ValueType> class SettingsModel : public AbstractSettingsModel<ValueType>
    {
      public:
        explicit SettingsModel(app::ApplicationCommon *app);
        explicit SettingsModel(sys::Service *app);

      protected:
        mutable settings::Settings settings;

A products/BellHybrid/apps/common/include/common/popups/BedtimeNotificationWindow.hpp => products/BellHybrid/apps/common/include/common/popups/BedtimeNotificationWindow.hpp +35 -0
@@ 0,0 1,35 @@
// 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 <apps-common/popups/WindowWithTimer.hpp>
#include <AsyncTask.hpp>

namespace app
{
    class ApplicationCommon;
}
namespace gui
{
    class Icon;

    class BedtimeNotificationWindow : public WindowWithTimer, public app::AsyncCallbackReceiver
    {
      private:
        static constexpr auto bedtimeNotificationIcon   = "big_bedtime_W_G";
        static constexpr auto bedtimeNotificationText   = "app_bell_bedtime_notification";
        static constexpr auto bedtimeNotificationTimout = std::chrono::seconds{6};

        app::ApplicationCommon *app;
        Icon *icon = nullptr;
        void onClose(CloseReason reason) override;
        bool onInput(const InputEvent &inputEvent) override;
        void returnToPreviousWindow();
        void buildInterface() override;

      public:
        explicit BedtimeNotificationWindow(app::ApplicationCommon *app);
        void onBeforeShow(ShowMode mode, SwitchData *data) override;
    };
} /* namespace gui */

M products/BellHybrid/apps/common/include/common/widgets/BellSideListItemWithCallbacks.hpp => products/BellHybrid/apps/common/include/common/widgets/BellSideListItemWithCallbacks.hpp +2 -0
@@ 19,6 19,8 @@ namespace gui
        std::function<void()> onEnter;
        std::function<void()> onExit;

        std::function<void()> onProceed;

      protected:
        void OnFocusChangedCallback();
    };

M products/BellHybrid/apps/common/include/common/widgets/ListItems.hpp => products/BellHybrid/apps/common/include/common/widgets/ListItems.hpp +16 -0
@@ 8,7 8,10 @@

#include <apps-common/widgets/spinners/SpinnerContents.hpp>
#include <apps-common/widgets/spinners/Spinners.hpp>
#include <apps-common/widgets/TimeSetFmtSpinner.hpp>

#include <i18n/i18n.hpp>
#include <time/dateCommon.hpp>

namespace gui
{


@@ 73,4 76,17 @@ namespace gui
      private:
        UTF8Spinner *spinner{};
    };

    class TimeListItem : public BellSideListItemWithCallbacks
    {
      public:
        explicit TimeListItem(AbstractSettingsModel<time_t> &model,
                              utils::time::Locale::TimeFormat fmt,
                              const std::string &focusFont,
                              const std::string &noFocusFont,
                              const std::string &topDescription = "");

      private:
        TimeSetFmtSpinner *spinner{};
    };
} // namespace gui

A products/BellHybrid/apps/common/include/common/windows/BellFinishedCallbackWindow.hpp => products/BellHybrid/apps/common/include/common/windows/BellFinishedCallbackWindow.hpp +30 -0
@@ 0,0 1,30 @@
// 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/data/BellFinishedCallbackWindowSwitchData.hpp>
#include <apps-common/messages/DialogMetadataMessage.hpp>
#include <apps-common/popups/WindowWithTimer.hpp>

namespace gui
{
    class Icon;

    class BellFinishedCallbackWindow : public WindowWithTimer
    {
      public:
        static constexpr auto defaultName = "BellFinishedCallbackWindow";

        explicit BellFinishedCallbackWindow(app::ApplicationCommon *app, const std::string &name = defaultName);

      protected:
        void buildInterface() override;
        bool onInput(const InputEvent &inputEvent) override;
        void onBeforeShow(ShowMode mode, SwitchData *data) override;

        Icon *icon{};
        std::function<void()> finishCallback = nullptr;
    };

} // namespace gui

M products/BellHybrid/apps/common/src/BellSideListItemWithCallbacks.cpp => products/BellHybrid/apps/common/src/BellSideListItemWithCallbacks.cpp +10 -1
@@ 1,6 1,8 @@
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include <module-gui/gui/input/InputEvent.hpp>

#include "widgets/BellSideListItemWithCallbacks.hpp"

namespace gui


@@ 19,7 21,14 @@ namespace gui
            return true;
        };

        inputCallback = [&](Item &, const InputEvent &inputEvent) -> bool { return body->onInput(inputEvent); };
        inputCallback = [&](Item &, const InputEvent &inputEvent) -> bool {
            if (inputEvent.isShortRelease(KeyCode::KEY_ENTER)) {
                if (onProceed) {
                    onProceed();
                }
            }
            return body->onInput(inputEvent);
        };
    }

    void BellSideListItemWithCallbacks::OnFocusChangedCallback()

A products/BellHybrid/apps/common/src/models/BedtimeModel.cpp => products/BellHybrid/apps/common/src/models/BedtimeModel.cpp +63 -0
@@ 0,0 1,63 @@
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include "models/BedtimeModel.hpp"

#include <apps-common/ApplicationCommon.hpp>
#include <db/SystemSettings.hpp>
#include <ctime>
namespace app::bell_bedtime
{
    void BedtimeOnOffModel::setValue(bool value)
    {
        const auto valStr = std::to_string(value);
        settings.setValue(bell::settings::Bedtime::active, valStr, settings::SettingsScope::Global);
    }

    auto BedtimeOnOffModel::getValue() const -> bool
    {
        const auto str = settings.getValue(bell::settings::Bedtime::active, settings::SettingsScope::Global);
        try {
            return std::stoi(str);
        }
        catch (const std::invalid_argument &) {
            return 0;
        }
    }

    auto BedtimeTimeModel::writeString(std::string str) -> void
    {
        settings.setValue(bell::settings::Bedtime::time, str, settings::SettingsScope::Global);
    }

    auto BedtimeTimeModel::readString() const -> std::string
    {
        return settings.getValue(bell::settings::Bedtime::time, settings::SettingsScope::Global);
    }

    auto BedtimeTimeModel::getTmFromString(const std::string &str, std::tm &tm) const -> bool
    {
        auto stringStream = std::istringstream(str);
        stringStream >> std::get_time(&tm, "%R");
        return bool(stringStream);
    }

    void BedtimeTimeModel::setValue(time_t value)
    {
        auto tm = std::localtime(&value);
        std::stringstream stringStream;
        stringStream << std::put_time(tm, "%R");
        writeString(stringStream.str());
    }

    auto BedtimeTimeModel::getValue() const -> time_t
    {
        const auto str = readString();
        std::tm tm     = {};
        if (!getTmFromString(str, tm)) {
            // incorrect time string
            getTmFromString(DEFAULT_BEDTIME_TIME, tm);
        }
        return std::mktime(&tm);
    }
} // namespace app::bell_bedtime

R products/BellHybrid/apps/application-bell-settings/models/SettingsModel.cpp => products/BellHybrid/apps/common/src/models/SettingsModel.cpp +3 -4
@@ 2,12 2,10 @@
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include <models/SettingsModel.hpp>

#include <apps-common/ApplicationCommon.hpp>

#include <utf8/UTF8.hpp>
namespace gui
{
    template <class ValueType> SettingsModel<ValueType>::SettingsModel(app::ApplicationCommon *app)
    template <class ValueType> SettingsModel<ValueType>::SettingsModel(sys::Service *app)
    {
        settings.init(service::ServiceProxy{app->weak_from_this()});
    }


@@ 16,4 14,5 @@ namespace gui
    template class SettingsModel<std::uint8_t>;
    template class SettingsModel<std::string>;
    template class SettingsModel<UTF8>;
    template class SettingsModel<time_t>;
} // namespace gui

A products/BellHybrid/apps/common/src/popups/BedtimeNotificationWindow.cpp => products/BellHybrid/apps/common/src/popups/BedtimeNotificationWindow.cpp +78 -0
@@ 0,0 1,78 @@
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include <apps-common/popups/Popups.hpp>
#include <common/popups/BedtimeNotificationWindow.hpp>
#include <gui/input/InputEvent.hpp>
#include <gui/widgets/Icon.hpp>
#include <i18n/i18n.hpp>
#include <purefs/filesystem_paths.hpp>
#include <service-audio/AudioServiceAPI.hpp>
#include <service-appmgr/Controller.hpp>

namespace gui
{
    BedtimeNotificationWindow::BedtimeNotificationWindow(app::ApplicationCommon *app)
        : WindowWithTimer(app, popup::window::bedtime_notification_window, bedtimeNotificationTimout),
          app::AsyncCallbackReceiver{app}, app{app}
    {
        buildInterface();
        timerCallback = [this](Item &, sys::Timer &) {
            returnToPreviousWindow();
            return true;
        };
    }

    void BedtimeNotificationWindow::buildInterface()
    {
        AppWindow::buildInterface();
        bottomBar->setText(BottomBar::Side::RIGHT, utils::translate(style::strings::common::back));
        setTitle("");

        icon = new Icon(this,
                        style::window::default_left_margin,
                        style::window::default_vertical_pos,
                        style::window::default_body_width,
                        style::window::default_body_height,
                        "",
                        "");

        icon->setAlignment(Alignment(Alignment::Horizontal::Center, Alignment::Vertical::Top));
        icon->image->setMargins(Margins(0, icon::image_top_margin, 0, icon::image_bottom_margin));
    }
    void BedtimeNotificationWindow::onBeforeShow(ShowMode mode, [[maybe_unused]] SwitchData *data)
    {
        WindowWithTimer::onBeforeShow(mode, data);
        icon->text->setRichText(utils::translate(bedtimeNotificationText));
        icon->image->set(bedtimeNotificationIcon);
        icon->resizeItems();
        statusBar->setVisible(false);
        header->setTitleVisibility(false);
        bottomBar->setActive(BottomBar::Side::RIGHT, false);
    }

    void BedtimeNotificationWindow::returnToPreviousWindow()
    {
        app::manager::Controller::sendAction(
            application,
            app::manager::actions::AbortPopup,
            std::make_unique<gui::PopupRequestParams>(gui::popup::ID::BedtimeNotification));
        application->returnToPreviousWindow();
    }

    bool BedtimeNotificationWindow::onInput(const InputEvent &inputEvent)
    {
        if (inputEvent.isShortRelease(KeyCode::KEY_ENTER) || inputEvent.isShortRelease(KeyCode::KEY_RF)) {
            returnToPreviousWindow();
            return true;
        }
        return false;
    }

    void BedtimeNotificationWindow::onClose(CloseReason reason)
    {
        auto stopPlaybackVec = std::vector<audio::PlaybackType>({audio::PlaybackType::Alarm});
        AudioServiceAPI::Stop(app, stopPlaybackVec);
    }

} /* namespace gui */

M products/BellHybrid/apps/common/src/widgets/ListItems.cpp => products/BellHybrid/apps/common/src/widgets/ListItems.cpp +20 -0
@@ 134,12 134,32 @@ namespace gui
        getValue = [&model, this]() { model.setValue(spinner->getCurrentValue()); };
        setValue = [&model, this]() { spinner->setCurrentValue(model.getValue()); };
    }

    void UTF8ListItem::setOnValueChanged(std::function<void(const UTF8 &)> &&cb)
    {
        spinner->onValueChanged = cb;
    }

    UTF8Spinner::Type UTF8ListItem::getCurrentValue()
    {
        return spinner->getCurrentValue();
    }

    TimeListItem::TimeListItem(AbstractSettingsModel<time_t> &model,
                               utils::time::Locale::TimeFormat timeFormat,
                               const std::string &focusFont,
                               const std::string &noFocusFont,
                               const std::string &topDescription)
        : BellSideListItemWithCallbacks(topDescription)
    {
        auto centerBox = dynamic_cast<HBox *>(body->getCenterBox());
        spinner        = new TimeSetFmtSpinner(centerBox);
        spinner->setMaximumSize(::style::bell_base_layout::w, ::style::bell_base_layout::h);
        spinner->setFont(focusFont, noFocusFont);
        spinner->setTimeFormat(timeFormat);
        spinner->setAlignment(Alignment(Alignment::Horizontal::Center, Alignment::Vertical::Center));

        getValue = [&model, this]() { model.setValue(spinner->getTime()); };
        setValue = [&model, this]() { spinner->setTime(model.getValue()); };
    }
} // namespace gui

A products/BellHybrid/apps/common/src/windows/BellFinishedCallbackWindow.cpp => products/BellHybrid/apps/common/src/windows/BellFinishedCallbackWindow.cpp +60 -0
@@ 0,0 1,60 @@
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include "common/windows/BellFinishedCallbackWindow.hpp"
#include "common/data/BellFinishedCallbackWindowSwitchData.hpp"
#include <apps-common/ApplicationCommon.hpp>
#include <gui/input/InputEvent.hpp>
#include <gui/widgets/Icon.hpp>

namespace gui
{

    BellFinishedCallbackWindow::BellFinishedCallbackWindow(app::ApplicationCommon *app, const std::string &name)
        : WindowWithTimer(app, name)
    {
        buildInterface();

        timerCallback = [this](Item &, sys::Timer &) {
            if (this->finishCallback) {
                this->finishCallback();
            }
            return true;
        };
    }

    void BellFinishedCallbackWindow::buildInterface()
    {
        WindowWithTimer::buildInterface();

        statusBar->setVisible(false);
        header->setTitleVisibility(false);
        bottomBar->setVisible(false);

        icon = new Icon(this, 0, 0, style::window_width, style::window_height, {}, {});
        icon->text->setFont(style::window::font::verybiglight);
    }

    bool BellFinishedCallbackWindow::onInput(const InputEvent &inputEvent)
    {
        if (inputEvent.isShortRelease(KeyCode::KEY_ENTER) || inputEvent.isShortRelease(KeyCode::KEY_RF)) {
            if (this->finishCallback) {
                this->finishCallback();
            }
            return true;
        }
        return false;
    }

    void BellFinishedCallbackWindow::onBeforeShow(ShowMode mode, SwitchData *data)
    {
        WindowWithTimer::onBeforeShow(mode, data);

        if (auto metadata = dynamic_cast<BellFinishedCallbackWindowSwitchData *>(data)) {
            icon->image->set(metadata->icon);
            icon->text->setText(metadata->text);
            finishCallback = metadata->finishCallback;
        }
    }

} // namespace gui

M products/BellHybrid/services/appmgr/ApplicationManager.cpp => products/BellHybrid/services/appmgr/ApplicationManager.cpp +1 -0
@@ 73,5 73,6 @@ namespace app::manager
        connect(typeid(AlarmActivated), convertibleToActionHandler);
        connect(typeid(AlarmDeactivated), convertibleToActionHandler);
        connect(typeid(BatteryShutdown), convertibleToActionHandler);
        connect(typeid(BedtimeNotification), convertibleToActionHandler);
    }
} // namespace app::manager

M products/BellHybrid/services/appmgr/include/appmgr/messages/AlarmMessage.hpp => products/BellHybrid/services/appmgr/include/appmgr/messages/AlarmMessage.hpp +14 -0
@@ 6,6 6,7 @@
#include <Service/Message.hpp>
#include <popups/AlarmActivatedPopupRequestParams.hpp>
#include <popups/AlarmDeactivatedPopupRequestParams.hpp>
#include <popups/BedtimeReminderPopupRequestParams.hpp>
#include <service-appmgr/Actions.hpp>
#include <service-appmgr/messages/ActionRequest.hpp>



@@ 34,3 35,16 @@ class AlarmDeactivated : public sys::DataMessage, public app::manager::actions::
            sender, app::manager::actions::ShowPopup, std::make_unique<gui::AlarmDeactivatedPopupRequestParams>());
    }
};

class BedtimeNotification : public sys::DataMessage, public app::manager::actions::ConvertibleToAction
{
  public:
    BedtimeNotification() : sys::DataMessage{MessageType::MessageTypeUninitialized}
    {}

    [[nodiscard]] auto toAction() const -> std::unique_ptr<app::manager::ActionRequest> override
    {
        return std::make_unique<app::manager::ActionRequest>(
            sender, app::manager::actions::ShowPopup, std::make_unique<gui::BedtimeReminderPopupRequestParams>());
    }
};

M products/BellHybrid/services/db/include/db/SystemSettings.hpp => products/BellHybrid/services/db/include/db/SystemSettings.hpp +5 -0
@@ 31,4 31,9 @@ namespace bell::settings
        constexpr inline auto lightActive = "alarm_light_active";
        constexpr inline auto duration    = "alarm_duration";
    } // namespace Alarm
    namespace Bedtime
    {
        constexpr inline auto active = "bedtime_active";
        constexpr inline auto time   = "bedtime_time";
    } // namespace Bedtime
};    // namespace bell::settings

M products/BellHybrid/services/time/AlarmOperations.cpp => products/BellHybrid/services/time/AlarmOperations.cpp +59 -3
@@ 7,6 7,7 @@

#include <service-db/Settings.hpp>
#include <db/SystemSettings.hpp>
#include <time/dateCommon.hpp>

namespace alarms
{


@@ 49,6 50,25 @@ namespace alarms
                "%s: enabled: %d; duration: %d minutes", path.data(), isEnabled, static_cast<int>(duration.count()));
            return {isEnabled, duration};
        }

        class BedtimeSettingsProviderImpl : public AbstractBedtimeSettingsProvider
        {
          public:
            explicit BedtimeSettingsProviderImpl(sys::Service *service)
                : bedtimeModel{std::make_unique<app::bell_bedtime::BedtimeModel>(service)}
            {}
            auto isBedtimeEnabled() -> bool override
            {
                return bedtimeModel.get()->getBedtimeOnOff().getValue();
            }
            auto getBedtimeTime() -> time_t override
            {
                return bedtimeModel.get()->getBedtimeTime().getValue();
            }

          private:
            std::unique_ptr<app::bell_bedtime::BedtimeModel> bedtimeModel;
        };
    } // namespace

    namespace


@@ 89,25 109,32 @@ namespace alarms
    {
        auto preWakeUpSettingsProvider   = std::make_unique<PreWakeUpSettingsProviderImpl>(service);
        auto snoozeChimeSettingsProvider = std::make_unique<SnoozeChimeSettingsProviderImpl>(service);
        auto bedtimeSettingsProvider     = std::make_unique<BedtimeSettingsProviderImpl>(service);
        auto alarmOperations             = std::make_unique<AlarmOperations>(std::move(alarmEventsRepo),
                                                                 getCurrentTimeCallback,
                                                                 std::move(preWakeUpSettingsProvider),
                                                                 std::move(snoozeChimeSettingsProvider));
                                                                 std::move(snoozeChimeSettingsProvider),
                                                                 std::move(bedtimeSettingsProvider));
        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::SnoozeChime,
                                                  std::make_shared<alarms::SnoozeChimeHandler>(service));
        alarmOperations->addAlarmExecutionHandler(alarms::AlarmType::BedtimeReminder,
                                                  std::make_shared<alarms::BedtimeReminderHandler>(service));

        return alarmOperations;
    }

    AlarmOperations::AlarmOperations(std::unique_ptr<AbstractAlarmEventsRepository> &&alarmEventsRepo,
                                     GetCurrentTime getCurrentTimeCallback,
                                     std::unique_ptr<PreWakeUpSettingsProvider> &&preWakeUpSettingsProvider,
                                     std::unique_ptr<SnoozeChimeSettingsProvider> &&snoozeChimeSettings)
                                     std::unique_ptr<SnoozeChimeSettingsProvider> &&snoozeChimeSettings,
                                     std::unique_ptr<AbstractBedtimeSettingsProvider> &&bedtimeSettingsProvider)
        : AlarmOperationsCommon{std::move(alarmEventsRepo), std::move(getCurrentTimeCallback)},
          preWakeUp(std::move(preWakeUpSettingsProvider)), snoozeChimeSettings(std::move(snoozeChimeSettings))
          preWakeUp(std::move(preWakeUpSettingsProvider)), snoozeChimeSettings(std::move(snoozeChimeSettings)),
          bedtime(std::move(bedtimeSettingsProvider))
    {}

    void AlarmOperations::minuteUpdated(TimePoint now)


@@ 115,6 142,7 @@ namespace alarms
        AlarmOperationsCommon::minuteUpdated(now);
        processPreWakeUp(now);
        processSnoozeChime(now);
        processBedtime(now);
    }

    void AlarmOperations::stopAllSnoozedAlarms()


@@ 141,6 169,15 @@ namespace alarms
        handlePreWakeUp(nextEvent, decision);
    }

    void AlarmOperations::processBedtime(TimePoint now)
    {
        if (bedtime.decide(now)) {
            auto bedtimeEvent           = std::make_shared<AlarmEventRecord>();
            bedtimeEvent.get()->enabled = true;
            handleAlarmEvent(bedtimeEvent, alarms::AlarmType::BedtimeReminder, true);
        }
    }

    void AlarmOperations::handlePreWakeUp(const SingleEventRecord &event, PreWakeUp::Decision decision)
    {
        if (auto alarmEventPtr = std::dynamic_pointer_cast<AlarmEventRecord>(event.parent); alarmEventPtr) {


@@ 208,4 245,23 @@ namespace alarms
        const auto expectedAlarmStart = std::chrono::floor<std::chrono::minutes>(now) + settings.timeBeforeAlarm;
        return settings.enabled && std::chrono::floor<std::chrono::minutes>(event.startDate) == expectedAlarmStart;
    }

    Bedtime::Bedtime(std::unique_ptr<AbstractBedtimeSettingsProvider> &&settingsProvider)
        : settingsProvider{std::move(settingsProvider)}
    {}

    auto Bedtime::decide(TimePoint now) -> bool
    {
        const auto activated = settingsProvider->isBedtimeEnabled();
        const auto time      = settingsProvider->getBedtimeTime();
        return activated && isTimeForBed(now, time);
    }

    auto Bedtime::isTimeForBed(const TimePoint &now, const time_t &bedtime) -> bool
    {
        auto time_tNow    = TimePointToTimeT(now);
        std::tm bedtimeTm = *std::localtime(&bedtime);
        std::tm checkTm   = *std::localtime(&time_tNow);
        return (bedtimeTm.tm_hour == checkTm.tm_hour && bedtimeTm.tm_min == checkTm.tm_min);
    }
} // namespace alarms

M products/BellHybrid/services/time/CMakeLists.txt => products/BellHybrid/services/time/CMakeLists.txt +2 -0
@@ 20,6 20,8 @@ target_link_libraries(bell-time
        module-sys
        bell::alarms
        bell::db
        application-bell-common
        utils-time
    PUBLIC
        service-time
)

M products/BellHybrid/services/time/include/time/AlarmOperations.hpp => products/BellHybrid/services/time/include/time/AlarmOperations.hpp +26 -1
@@ 5,6 5,7 @@

#include <AlarmOperations.hpp>
#include <db/SystemSettings.hpp>
#include <common/models/BedtimeModel.hpp>

namespace alarms
{


@@ 44,6 45,14 @@ namespace alarms
        virtual auto getSettings() -> Settings          = 0;
    };

    class AbstractBedtimeSettingsProvider
    {
      public:
        virtual ~AbstractBedtimeSettingsProvider() noexcept = default;
        virtual auto isBedtimeEnabled() -> bool             = 0;
        virtual auto getBedtimeTime() -> time_t             = 0;
    };

    class PreWakeUp
    {
      public:


@@ 64,13 73,26 @@ namespace alarms
        std::unique_ptr<PreWakeUpSettingsProvider> settingsProvider;
    };

    class Bedtime
    {
      public:
        explicit Bedtime(std::unique_ptr<AbstractBedtimeSettingsProvider> &&settingsProvider);
        auto decide(TimePoint now) -> bool;

      private:
        auto isTimeForBed(const TimePoint &now, const time_t &bedtime) -> bool;

        const std::unique_ptr<AbstractBedtimeSettingsProvider> settingsProvider;
    };

    class AlarmOperations : public AlarmOperationsCommon
    {
      public:
        AlarmOperations(std::unique_ptr<AbstractAlarmEventsRepository> &&alarmEventsRepo,
                        GetCurrentTime getCurrentTimeCallback,
                        std::unique_ptr<PreWakeUpSettingsProvider> &&preWakeUpSettingsProvider,
                        std::unique_ptr<SnoozeChimeSettingsProvider> &&snoozeChimeSettingsProvider);
                        std::unique_ptr<SnoozeChimeSettingsProvider> &&snoozeChimeSettingsProvider,
                        std::unique_ptr<AbstractBedtimeSettingsProvider> &&BedtimeModel);

        void minuteUpdated(TimePoint now) override;
        void stopAllSnoozedAlarms() override;


@@ 81,8 103,11 @@ namespace alarms
      private:
        void handlePreWakeUp(const SingleEventRecord &event, PreWakeUp::Decision decision);
        void handleSnoozeChime(const SingleEventRecord &event, bool newStateOn);
        void handleBedtime(const SingleEventRecord &event, bool decision);
        void processBedtime(TimePoint now);

        PreWakeUp preWakeUp;
        std::unique_ptr<SnoozeChimeSettingsProvider> snoozeChimeSettings;
        Bedtime bedtime;
    };
} // namespace alarms

M products/BellHybrid/services/time/tests/test-BellAlarmOperations.cpp => products/BellHybrid/services/time/tests/test-BellAlarmOperations.cpp +50 -4
@@ 2,6 2,7 @@
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include <AlarmOperations.hpp>
#include <common/models/BedtimeModel.hpp>
#include <module-db/Interface/AlarmEventRecord.hpp>

#include <products/BellHybrid/services/time/include/time/AlarmOperations.hpp>


@@ 61,15 62,38 @@ namespace
        Settings settings{true, std::chrono::minutes{1}};
    };

    class MockedBedtimeModel : public alarms::AbstractBedtimeSettingsProvider
    {
      public:
        MockedBedtimeModel() : bedtimeOnOff{false}, bedtimeTime{0}
        {}
        MockedBedtimeModel(bool OnOff, TimePoint time) : bedtimeOnOff{OnOff}, bedtimeTime{TimePointToTimeT(time)}
        {}
        auto isBedtimeEnabled() -> bool override
        {
            return bedtimeOnOff;
        }
        auto getBedtimeTime() -> time_t override
        {
            return bedtimeTime;
        }

      private:
        bool bedtimeOnOff;
        time_t bedtimeTime;
    };

    std::unique_ptr<alarms::IAlarmOperations> getMockedAlarmOperations(
        std::unique_ptr<MockAlarmEventsRepository> &alarmRepo,
        std::unique_ptr<alarms::PreWakeUpSettingsProvider> &&preWakeUpSettingsProvider,
        std::unique_ptr<alarms::SnoozeChimeSettingsProvider> &&snoozeChimeSettingsProvider)
        std::unique_ptr<alarms::SnoozeChimeSettingsProvider> &&snoozeChimeSettingsProvider,
        std::unique_ptr<alarms::AbstractBedtimeSettingsProvider> &&bedtimeSettingsProvider)
    {
        return std::make_unique<alarms::AlarmOperations>(std::move(alarmRepo),
                                                         timeInjector,
                                                         std::move(preWakeUpSettingsProvider),
                                                         std::move(snoozeChimeSettingsProvider));
                                                         std::move(snoozeChimeSettingsProvider),
                                                         std::move(bedtimeSettingsProvider));
    }
} // namespace



@@ 79,7 103,8 @@ std::unique_ptr<alarms::IAlarmOperations> AlarmOperationsFixture::getMockedAlarm
{
    return ::getMockedAlarmOperations(alarmRepo,
                                      std::make_unique<MockedPreWakeUpSettingsProvider>(),
                                      std::make_unique<MockedSnoozeChimeSettingsProvider>());
                                      std::make_unique<MockedSnoozeChimeSettingsProvider>(),
                                      std::make_unique<MockedBedtimeModel>());
}

TEST(PreWakeUp, TooEarlyForPreWakeUp)


@@ 186,6 211,26 @@ TEST(PreWakeUp, TimeToLightFrontlightButDisabled)
    ASSERT_FALSE(decision.timeForFrontlight);
}

TEST(Bedtime, TimeToBedDisabled)
{
    auto settingsProvider = std::make_unique<MockedBedtimeModel>(false, TimePointFromString("2022-11-11 05:02:00"));
    alarms::Bedtime bedtime(std::move(settingsProvider));
    ASSERT_FALSE(bedtime.decide(TimePointFromString("2022-11-11 05:02:00")));
    ASSERT_FALSE(bedtime.decide(TimePointFromString("2022-11-11 07:32:00")));
}

TEST(Bedtime, TimeToBedEnabled)
{
    auto settingsProvider = std::make_unique<MockedBedtimeModel>(true, TimePointFromString("2022-11-11 05:02:00"));
    alarms::Bedtime bedtime(std::move(settingsProvider));
    ASSERT_TRUE(bedtime.decide(TimePointFromString("2022-11-11 05:02:00")));
    ASSERT_TRUE(bedtime.decide(TimePointFromString("2022-12-03 05:02:01")));
    ASSERT_TRUE(bedtime.decide(TimePointFromString("2022-12-03 05:02:03")));
    ASSERT_TRUE(bedtime.decide(TimePointFromString("2022-12-03 05:02:55")));
    ASSERT_FALSE(bedtime.decide(TimePointFromString("2022-11-11 07:32:00")));
    ASSERT_FALSE(bedtime.decide(TimePointFromString("2022-11-11 05:01:59")));
}

TEST(PreWakeUp, TimePointIsNotRoundedToFullMinute)
{
    alarms::PreWakeUp preWakeUp(std::make_unique<MockedPreWakeUpSettingsProvider>());


@@ 226,7 271,8 @@ class BellAlarmOperationsFixture : public ::testing::Test

        alarmOperations = ::getMockedAlarmOperations(alarmRepoMock,
                                                     std::make_unique<MockedPreWakeUpSettingsProvider>(),
                                                     std::make_unique<MockedSnoozeChimeSettingsProvider>());
                                                     std::make_unique<MockedSnoozeChimeSettingsProvider>(),
                                                     std::make_unique<MockedBedtimeModel>());
        alarmOperations->addAlarmExecutionHandler(alarms::AlarmType::PreWakeUpChime, chimeHandler);
        alarmOperations->addAlarmExecutionHandler(alarms::AlarmType::PreWakeUpFrontlight, frontlightHandler);
        alarmOperations->updateEventsCache(TimePointFromString("2022-11-11 08:00:00"));