~aleteoryx/muditaos

ff089da0daf042dd515805118808342b47cb3872 — rrandomsky 1 year, 7 months ago 6719ccf
[BH-1899] Add low battery screen before starting focus session

If the battery is discharged below 10%, the user gets a
notification before starting the focus session.
25 files changed, 233 insertions(+), 88 deletions(-)

M image/system_a/data/lang/English.json
M module-apps/apps-common/WindowsStack.cpp
M module-apps/apps-common/WindowsStack.hpp
M products/BellHybrid/apps/application-bell-focus-timer/ApplicationFocusTimer.cpp
M products/BellHybrid/apps/application-bell-focus-timer/CMakeLists.txt
M products/BellHybrid/apps/application-bell-focus-timer/data/FocusCommon.hpp
M products/BellHybrid/apps/application-bell-focus-timer/models/FocusSettingsModel.cpp
A products/BellHybrid/apps/application-bell-focus-timer/presenter/FocusMainPresenter.cpp
A products/BellHybrid/apps/application-bell-focus-timer/presenter/FocusMainPresenter.hpp
M products/BellHybrid/apps/application-bell-focus-timer/presenter/FocusTimerPresenter.cpp
M products/BellHybrid/apps/application-bell-focus-timer/presenter/FocusTimerPresenter.hpp
M products/BellHybrid/apps/application-bell-focus-timer/windows/FocusMainWindow.cpp
M products/BellHybrid/apps/application-bell-focus-timer/windows/FocusMainWindow.hpp
M products/BellHybrid/apps/application-bell-focus-timer/windows/FocusTimerWindow.cpp
M products/BellHybrid/apps/application-bell-focus-timer/windows/FocusTimerWindow.hpp
M products/BellHybrid/apps/application-bell-relaxation/presenter/RelaxationEndedPresenter.cpp
M products/BellHybrid/apps/common/include/common/data/BatteryStatusSwitchData.hpp
M products/BellHybrid/apps/common/include/common/popups/BedtimeNotificationWindow.hpp
M products/BellHybrid/apps/common/include/common/windows/BellFinishedWindow.hpp
M products/BellHybrid/apps/common/src/models/LowBatteryInfoModel.cpp
M products/BellHybrid/apps/common/src/options/BellOptionWindow.cpp
M products/BellHybrid/apps/common/src/popups/BedtimeNotificationWindow.cpp
M products/BellHybrid/apps/common/src/windows/BellFinishedWindow.cpp
M products/BellHybrid/services/appmgr/IdleHandler.cpp
M products/BellHybrid/services/appmgr/include/appmgr/IdleHandler.hpp
M image/system_a/data/lang/English.json => image/system_a/data/lang/English.json +1 -1
@@ 103,7 103,7 @@
    "app_bell_relaxation_sounds": "Relaxation sounds",
    "app_bell_relaxation_timer_title": "Relaxation time",
    "app_bell_relaxation_uploaded_sounds": "Uploaded sounds",
    "app_bell_focus_timer_summary": "<text>Well done!  <token>$VALUE</token> focus complete.</text>",
    "app_bell_focus_timer_summary": "<text>Well done!  <token>$VALUE</token> focus<br></br>complete.</text>",
    "app_bell_reset_message": "<text>Resetting Mudita<br />Harmony</text>",
    "app_bell_settings_about": "About",
    "app_bell_settings_about_info_text": "www.mudita.com",

M module-apps/apps-common/WindowsStack.cpp => module-apps/apps-common/WindowsStack.cpp +5 -5
@@ 1,4 1,4 @@
// Copyright (c) 2017-2023, Mudita Sp. z.o.o. All rights reserved.
// Copyright (c) 2017-2024, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include "WindowsStack.hpp"


@@ 25,7 25,7 @@ namespace app
    {
        /// Note: this is the place which will destroy old window if there was one
        windows[name] = std::move(window);
        stack.push_back(WindowData(name, disposition));
        stack.emplace_back(name, disposition);
    }

    gui::AppWindow *WindowsStack::get(const std::string &name) const


@@ 34,7 34,7 @@ namespace app
        return ret == std::end(windows) ? nullptr : ret->second.get();
    }

    std::optional<WindowData> WindowsStack::getWindowData(uint32_t depth) const
    std::optional<WindowData> WindowsStack::getWindowData(std::uint32_t depth) const
    {
        if (depth >= stack.size()) {
            return std::nullopt;


@@ 42,7 42,7 @@ namespace app
        return {*std::prev(stack.end(), depth + 1)};
    }

    std::optional<std::string> WindowsStack::get(uint32_t depth) const
    std::optional<std::string> WindowsStack::get(std::uint32_t depth) const
    {
        if (auto windowData = getWindowData(depth)) {
            return {windowData->name};


@@ 135,9 135,9 @@ namespace app
            std::advance(it, 1);
        }
    }

    std::size_t WindowsStack::getSize() const noexcept
    {
        return stack.size();
    }

} // namespace app

M module-apps/apps-common/WindowsStack.hpp => module-apps/apps-common/WindowsStack.hpp +8 -10
@@ 1,4 1,4 @@
// Copyright (c) 2017-2023, Mudita Sp. z.o.o. All rights reserved.
// Copyright (c) 2017-2024, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#pragma once


@@ 20,12 20,11 @@ namespace gui

namespace app
{

    class WindowsFactory;
    class ApplicationCommon;

    constexpr auto previousWindow = 1;
    constexpr auto topWindow      = 0;
    inline constexpr auto previousWindow = 1;
    inline constexpr auto topWindow      = 0;

    struct WindowData
    {


@@ 48,8 47,8 @@ namespace app
        WindowsStack() = default;

        /// iterators, unfortunately used in applications
        std::map<std::string, std::unique_ptr<gui::AppWindow>>::const_iterator begin() const;
        std::map<std::string, std::unique_ptr<gui::AppWindow>>::const_iterator end() const;
        [[nodiscard]] std::map<std::string, std::unique_ptr<gui::AppWindow>>::const_iterator begin() const;
        [[nodiscard]] std::map<std::string, std::unique_ptr<gui::AppWindow>>::const_iterator end() const;
        [[nodiscard]] bool isEmpty() const noexcept;
        [[nodiscard]] std::size_t getSize() const noexcept;



@@ 59,9 58,9 @@ namespace app
                  const gui::popup::Disposition &disposition = gui::popup::WindowDisposition);

        /// window getters
        gui::AppWindow *get(const std::string &name) const;
        std::optional<std::string> get(uint32_t depth = 0) const;
        std::optional<WindowData> getWindowData(uint32_t depth = 0) const;
        [[nodiscard]] gui::AppWindow *get(const std::string &name) const;
        [[nodiscard]] std::optional<std::string> get(std::uint32_t depth = 0) const;
        [[nodiscard]] std::optional<WindowData> getWindowData(std::uint32_t depth = 0) const;

        /// functions removing windows from stack
        /// `pop`  functions - handle last, latest window


@@ 78,5 77,4 @@ namespace app

        bool rebuildWindows(app::WindowsFactory &windowsFactory, ApplicationCommon *app);
    };

} // namespace app

M products/BellHybrid/apps/application-bell-focus-timer/ApplicationFocusTimer.cpp => products/BellHybrid/apps/application-bell-focus-timer/ApplicationFocusTimer.cpp +9 -2
@@ 8,15 8,16 @@
#include "windows/FocusSettingsWindow.hpp"
#include "windows/FocusTimerWindow.hpp"

#include "presenter/FocusMainPresenter.hpp"
#include "presenter/FocusSettingsPresenter.hpp"
#include "presenter/FocusTimerPresenter.hpp"

#include "models/FocusSettingsModel.hpp"

#include "common/models/TimeModel.hpp"
#include <common/models/AudioModel.hpp>
#include <common/windows/SessionPausedWindow.hpp>
#include <common/windows/BellFinishedWindow.hpp>
#include <common/windows/AppsBatteryStatusWindow.hpp>
#include <system/messages/SentinelRegistrationMessage.hpp>

namespace app


@@ 66,7 67,8 @@ namespace app
    void ApplicationFocusTimer::createUserInterface()
    {
        windowsFactory.attach(focus::window::name::main, [this](ApplicationCommon *app, const std::string &name) {
            return std::make_unique<focus::FocusMainWindow>(app);
            auto presenter = std::make_unique<app::focus::FocusMainPresenter>(*batteryModel, *lowBatteryInfoModel);
            return std::make_unique<focus::FocusMainWindow>(app, std::move(presenter));
        });

        windowsFactory.attach(focus::window::name::settings, [this](ApplicationCommon *app, const std::string &name) {


@@ 97,6 99,11 @@ namespace app
                                  return std::make_unique<gui::BellFinishedWindow>(app, name);
                              });

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

        attachPopups({gui::popup::ID::AlarmActivated,
                      gui::popup::ID::AlarmDeactivated,
                      gui::popup::ID::PowerOff,

M products/BellHybrid/apps/application-bell-focus-timer/CMakeLists.txt => products/BellHybrid/apps/application-bell-focus-timer/CMakeLists.txt +5 -0
@@ 21,11 21,15 @@ target_include_directories(application-bell-focus-timer
target_sources(application-bell-focus-timer
    PRIVATE
        ApplicationFocusTimer.cpp
        
        windows/FocusMainWindow.cpp
        windows/FocusSettingsWindow.cpp
        windows/FocusTimerWindow.cpp

        presenter/FocusMainPresenter.cpp
        presenter/FocusSettingsPresenter.cpp
        presenter/FocusTimerPresenter.cpp

        models/FocusSettingsModel.cpp

    PUBLIC


@@ 37,6 41,7 @@ target_link_libraries(application-bell-focus-timer
        app
        bell::app-common
        bell::app-main
        bell::audio
        bell::keymap
        bell::paths
        bell::db

M products/BellHybrid/apps/application-bell-focus-timer/data/FocusCommon.hpp => products/BellHybrid/apps/application-bell-focus-timer/data/FocusCommon.hpp +4 -3
@@ 12,9 12,10 @@ namespace app::focus
{
    namespace window::name
    {
        inline constexpr auto main     = gui::name::window::main_window;
        inline constexpr auto settings = "FocusTimerSettingsWindow";
        inline constexpr auto timer    = "FocusTimerSessionWindow";
        inline constexpr auto main                 = gui::name::window::main_window;
        inline constexpr auto settings             = "FocusTimerSettingsWindow";
        inline constexpr auto timer                = "FocusTimerSessionWindow";
        inline constexpr auto focusTimerLowBattery = "FocusTimerLowBatteryWindow";
    } // namespace window::name

    inline std::filesystem::path getFocusTimeAudioPath()

M products/BellHybrid/apps/application-bell-focus-timer/models/FocusSettingsModel.cpp => products/BellHybrid/apps/application-bell-focus-timer/models/FocusSettingsModel.cpp +1 -0
@@ 14,6 14,7 @@ namespace app::focus::models
    {
        settings.setValue(name, std::to_string(value));
    }

    std::uint8_t FocusSettingsModel::getValue() const
    {
        const auto &value = settings.getValue(name);

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

#include "FocusMainPresenter.hpp"

namespace app::focus
{
    FocusMainPresenter::FocusMainPresenter(AbstractBatteryModel &batteryModel,
                                           AbstractLowBatteryInfoModel &lowBatteryInfoModel)
        : batteryModel{batteryModel}, lowBatteryInfoModel{lowBatteryInfoModel}
    {}

    Store::Battery FocusMainPresenter::getBatteryState()
    {
        return batteryModel.getLevelState();
    }

    bool FocusMainPresenter::isBatteryCharging(Store::Battery::State state) const
    {
        return batteryModel.isBatteryCharging(state);
    }

    bool FocusMainPresenter::isBatteryBelowLowLevelThreshold(units::SOC soc) const
    {
        return soc < constants::lowBatteryInfoThreshold;
    }

    bool FocusMainPresenter::isLowBatteryWindowHandled() const
    {
        return lowBatteryInfoModel.isInfoHandled();
    }

    void FocusMainPresenter::handleLowBatteryWindow()
    {
        lowBatteryInfoModel.handleInfo();
    }
} // namespace app::focus

A products/BellHybrid/apps/application-bell-focus-timer/presenter/FocusMainPresenter.hpp => products/BellHybrid/apps/application-bell-focus-timer/presenter/FocusMainPresenter.hpp +54 -0
@@ 0,0 1,54 @@
// Copyright (c) 2017-2024, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#pragma once

#include <apps-common/BasePresenter.hpp>
#include <common/models/BatteryModel.hpp>
#include <common/models/LowBatteryInfoModel.hpp>
#include <chrono>
#include <vector>

namespace app
{
    class ApplicationCommon;
}

namespace app::focus
{
    class FocusMainContract
    {
      public:
        class View
        {
          public:
            virtual ~View() = default;
        };

        class Presenter : public BasePresenter<FocusMainContract::View>
        {
          public:
            virtual ~Presenter()                                               = default;
            virtual Store::Battery getBatteryState()                           = 0;
            virtual bool isBatteryCharging(Store::Battery::State state) const  = 0;
            virtual bool isBatteryBelowLowLevelThreshold(units::SOC soc) const = 0;
            [[nodiscard]] virtual bool isLowBatteryWindowHandled() const       = 0;
            virtual void handleLowBatteryWindow()                              = 0;
        };
    };

    class FocusMainPresenter : public FocusMainContract::Presenter
    {
        AbstractBatteryModel &batteryModel;
        AbstractLowBatteryInfoModel &lowBatteryInfoModel;

        Store::Battery getBatteryState() override;
        [[nodiscard]] bool isBatteryCharging(Store::Battery::State state) const override;
        [[nodiscard]] bool isBatteryBelowLowLevelThreshold(units::SOC soc) const override;
        [[nodiscard]] bool isLowBatteryWindowHandled() const override;
        void handleLowBatteryWindow() override;

      public:
        FocusMainPresenter(AbstractBatteryModel &batteryModel, AbstractLowBatteryInfoModel &lowBatteryInfoModel);
    };
} // namespace app::focus

M products/BellHybrid/apps/application-bell-focus-timer/presenter/FocusTimerPresenter.cpp => products/BellHybrid/apps/application-bell-focus-timer/presenter/FocusTimerPresenter.cpp +18 -8
@@ 10,10 10,13 @@
#include <common/windows/BellFinishedWindow.hpp>
#include <common/LanguageUtils.hpp>

#include <audio/AudioMessage.hpp>

namespace
{
    constexpr std::chrono::seconds delayBetweenSessions{5};
    constexpr std::chrono::seconds summaryWindowTimeout{5};
    constexpr auto delayBetweenSessions{std::chrono::seconds{5}};
    constexpr auto delayBetweenSessionsTimerName{"betweenSessionTimer"};
    constexpr auto summaryWindowTimeout{std::chrono::seconds{5}};

    std::string createSummaryText(const std::string &str, const std::string &minutesOfFocus)
    {


@@ 26,7 29,6 @@ namespace

namespace app::focus
{

    FocusTimerPresenter::FocusTimerPresenter(app::ApplicationCommon *app,
                                             models::FocusSettingsModel &focusTimeModel,
                                             models::FocusSettingsModel &focusRepeatsModel,


@@ 44,7 46,9 @@ namespace app::focus
        focusSessionsLeft     = allFocusSessionsCount;

        betweenSessionTimer = sys::TimerFactory::createSingleShotTimer(
            app, "betweenSessionTimer", delayBetweenSessions, [this](sys::Timer &) { executeNextStep(); });
            app, delayBetweenSessionsTimerName, delayBetweenSessions, [this]([[maybe_unused]] sys::Timer &t) {
                executeNextStep();
            });
    }

    void FocusTimerPresenter::setTimer(std::unique_ptr<app::TimerWithCallbacks> &&_timer)


@@ 105,10 109,10 @@ namespace app::focus
        const auto elapsed        = std::chrono::duration_cast<std::chrono::minutes>(timer->getElapsed());
        const auto minutesInFocus = ((currentTimerPhase == FocusTimerPhase::FocusTime) ? elapsed.count() : 0) +
                                    (allFocusSessionsCount - focusSessionsLeft) * focusSessionDuration.count();
        const auto sumOfFocusTime =
        const auto &sumOfFocusTime =
            std::to_string(minutesInFocus) + " " + utils::language::getCorrectMinutesAccusativeForm(minutesInFocus);
        const auto textToComplete = utils::translate("app_bell_focus_timer_summary");
        const auto summaryText    = createSummaryText(textToComplete, sumOfFocusTime);
        const auto &textToComplete = utils::translate("app_bell_focus_timer_summary");
        const auto &summaryText    = createSummaryText(textToComplete, sumOfFocusTime);

        app->switchWindow(
            gui::window::bell_finished::defaultName,


@@ 156,6 160,13 @@ namespace app::focus
        getView()->setTimeFormat(timeModel->getTimeFormat());
    }

    void FocusTimerPresenter::playGong()
    {
        auto msg = std::make_shared<service::AudioStartPlaybackRequest>(app::focus::getFocusTimeAudioPath(),
                                                                        audio::PlaybackType::Meditation);
        app->bus.sendUnicast(std::move(msg), service::audioServiceName);
    }

    void FocusTimerPresenter::startTime()
    {
        switch (currentTimerPhase) {


@@ 212,5 223,4 @@ namespace app::focus
        getView()->showFocusSessionCountdown();
        return FocusTimerPhase::FocusTime;
    }

} // namespace app::focus

M products/BellHybrid/apps/application-bell-focus-timer/presenter/FocusTimerPresenter.hpp => products/BellHybrid/apps/application-bell-focus-timer/presenter/FocusTimerPresenter.hpp +2 -0
@@ 57,6 57,7 @@ namespace app::focus
            virtual void abandon()                                                  = 0;
            virtual void finish()                                                   = 0;
            virtual void onBeforeShow()                                             = 0;
            virtual void playGong()                                                 = 0;
        };
    };



@@ 82,6 83,7 @@ namespace app::focus
        void abandon() override;
        void finish() override;
        void onBeforeShow() override;
        void playGong() override;
        void startTime();

      private:

M products/BellHybrid/apps/application-bell-focus-timer/windows/FocusMainWindow.cpp => products/BellHybrid/apps/application-bell-focus-timer/windows/FocusMainWindow.cpp +39 -3
@@ 7,17 7,27 @@
#include "FocusTimerWindow.hpp"

#include <common/options/OptionBellMenu.hpp>
#include <common/data/BatteryStatusSwitchData.hpp>

namespace app::focus
{
    using namespace gui;
    FocusMainWindow::FocusMainWindow(app::ApplicationCommon *app, const std::string name)
        : BellOptionWindow(app, std::move(name))

    FocusMainWindow::FocusMainWindow(app::ApplicationCommon *app,
                                     std::unique_ptr<app::focus::FocusMainContract::Presenter> &&presenter,
                                     const std::string &name)
        : BellOptionWindow(app, name), presenter(std::move(presenter))
    {
        addOptions(settingsOptionsList());
        setListTitle(utils::translate("app_bellmain_focus_timer"));
    }

    void FocusMainWindow::onBeforeShow(ShowMode mode, SwitchData *data)
    {
        BellOptionWindow::onBeforeShow(mode, data);
        static_cast<app::Application *>(application)->resumeIdleTimer();
    }

    std::list<Option> FocusMainWindow::settingsOptionsList()
    {
        using ActivatedCallback = std::function<bool(gui::Item &)>;


@@ 33,6 43,32 @@ namespace app::focus
            };
        };

        auto startFocusCallback = [this](const std::string &window) {
            startFocus = [window, this]() {
                if (window.empty()) {
                    return;
                }
                application->switchWindow(window);
            };
            return [window, this](gui::Item &) {
                const auto batteryState = presenter->getBatteryState();
                const auto soc          = batteryState.level;
                const auto isCharging   = presenter->isBatteryCharging(batteryState.state);
                if (!presenter->isLowBatteryWindowHandled() && !isCharging &&
                    presenter->isBatteryBelowLowLevelThreshold(soc)) {
                    auto lowBatterySwitchData =
                        std::make_unique<AppsBatteryStatusSwitchData>(soc, isCharging, startFocus);
                    application->switchWindow(focus::window::name::focusTimerLowBattery,
                                              std::move(lowBatterySwitchData));
                    presenter->handleLowBatteryWindow();
                }
                else {
                    startFocus();
                }
                return true;
            };
        };

        std::list<gui::Option> settingsOptionList;
        auto addWinSettings = [&](const UTF8 &name, const std::string &window, Callback &&callback) {
            settingsOptionList.emplace_back(std::make_unique<gui::option::OptionBellMenu>(


@@ 45,7 81,7 @@ namespace app::focus
                this));
        };

        addWinSettings(utils::translate("app_bell_focus_start"), window::name::timer, defaultCallback);
        addWinSettings(utils::translate("app_bell_focus_start"), window::name::timer, startFocusCallback);
        addWinSettings(utils::translate("app_bell_focus_settings"), window::name::settings, defaultCallback);

        return settingsOptionList;

M products/BellHybrid/apps/application-bell-focus-timer/windows/FocusMainWindow.hpp => products/BellHybrid/apps/application-bell-focus-timer/windows/FocusMainWindow.hpp +12 -4
@@ 5,16 5,24 @@

#include "FocusCommon.hpp"
#include <common/options/BellOptionWindow.hpp>
#include <presenter/FocusMainPresenter.hpp>

namespace app::focus
{
    class FocusMainWindow : public gui::BellOptionWindow
    using namespace gui;

    class FocusMainWindow : public BellOptionWindow, public app::focus::FocusMainContract::View
    {
      public:
        explicit FocusMainWindow(app::ApplicationCommon *app, const std::string name = window::name::main);
        FocusMainWindow(app::ApplicationCommon *app,
                        std::unique_ptr<app::focus::FocusMainContract::Presenter> &&presenter,
                        const std::string &name = window::name::main);

        void onBeforeShow(ShowMode mode, SwitchData *data) override;

      private:
        std::list<gui::Option> settingsOptionsList();
        std::unique_ptr<app::focus::FocusMainContract::Presenter> presenter;
        std::list<Option> settingsOptionsList();
        std::function<void()> startFocus;
    };

} // namespace app::focus

M products/BellHybrid/apps/application-bell-focus-timer/windows/FocusTimerWindow.cpp => products/BellHybrid/apps/application-bell-focus-timer/windows/FocusTimerWindow.cpp +8 -16
@@ 5,7 5,6 @@
#include <data/FocusTimerStyle.hpp>

#include <Application.hpp>
#include <products/BellHybrid/services/audio/include/audio/AudioMessage.hpp>
#include <apps-common/widgets/BellBaseLayout.hpp>
#include <apps-common/ApplicationCommon.hpp>
#include <apps-common/widgets/ProgressTimerWithBarGraphAndCounter.hpp>


@@ 13,9 12,9 @@

namespace
{
    constexpr auto focusTimerProgressTimerName{"FocusProgressTimer"};
    constexpr std::chrono::seconds focusTimerProgressTimerPeriod{1};
    constexpr auto focusTimerProgressMode{app::ProgressCountdownMode::Increasing};
    constexpr auto progressTimerName{"FocusProgressTimer"};
    constexpr auto progressTimerPeriod{std::chrono::seconds{1}};
    constexpr auto progressMode{app::ProgressCountdownMode::Increasing};
    constexpr auto focusTimerText{"Focus timer"};
    constexpr auto timeToFocusText{"Time to focus"};
    constexpr auto shortBreakTimeText{"Short break"};


@@ 122,7 121,7 @@ namespace app::focus
        presenter->onBeforeShow();
        updateTime();
        if (mode == gui::ShowMode::GUI_SHOW_INIT) {
            playGong();
            presenter->playGong();
            presenter->start();
        }
    }


@@ 158,7 157,7 @@ namespace app::focus
        bottomDescription->setVisible(true);
        bottomDescription->setText(endOfAllSessionText);
        mainVBox->resizeItems();
        playGong();
        presenter->playGong();
    }

    void FocusTimerWindow::showFocusSessionCountdown()


@@ 179,7 178,7 @@ namespace app::focus
        bottomDescription->setVisible(true);
        bottomDescription->setText(timeForBreakText);
        mainVBox->resizeItems();
        playGong();
        presenter->playGong();
    }

    void FocusTimerWindow::showShortBreakCountdown()


@@ 200,7 199,7 @@ namespace app::focus
        bottomDescription->setVisible(true);
        bottomDescription->setText(timeToFocusText);
        mainVBox->resizeItems();
        playGong();
        presenter->playGong();
    }

    void FocusTimerWindow::pause()


@@ 222,7 221,7 @@ namespace app::focus
    void FocusTimerWindow::configureTimer()
    {
        auto progressTimer = std::make_unique<app::ProgressTimerWithBarGraphAndCounter>(
            application, *this, focusTimerProgressTimerName, focusTimerProgressTimerPeriod, focusTimerProgressMode);
            application, *this, progressTimerName, progressTimerPeriod, progressMode);
        progressTimer->attach(progress);
        progressTimer->attach(timer);
        presenter->setTimer(std::move(progressTimer));


@@ 246,11 245,4 @@ namespace app::focus
        }
        return gui::RefreshModes::GUI_REFRESH_FAST;
    }

    void FocusTimerWindow::playGong()
    {
        auto msg = std::make_shared<service::AudioStartPlaybackRequest>(app::focus::getFocusTimeAudioPath(),
                                                                        audio::PlaybackType::Meditation);
        application->bus.sendUnicast(std::move(msg), service::audioServiceName);
    }
} // namespace app::focus

M products/BellHybrid/apps/application-bell-focus-timer/windows/FocusTimerWindow.hpp => products/BellHybrid/apps/application-bell-focus-timer/windows/FocusTimerWindow.hpp +0 -2
@@ 49,7 49,5 @@ namespace app::focus

        void buildLayout();
        void configureTimer();

        void playGong();
    };
} // namespace app::focus

M products/BellHybrid/apps/application-bell-relaxation/presenter/RelaxationEndedPresenter.cpp => products/BellHybrid/apps/application-bell-relaxation/presenter/RelaxationEndedPresenter.cpp +1 -2
@@ 1,10 1,9 @@
// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
// Copyright (c) 2017-2024, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include "ApplicationBellRelaxation.hpp"
#include "presenter/RelaxationEndedPresenter.hpp"

#include <Application.hpp>
#include <service-appmgr/Controller.hpp>

namespace app::relaxation

M products/BellHybrid/apps/common/include/common/data/BatteryStatusSwitchData.hpp => products/BellHybrid/apps/common/include/common/data/BatteryStatusSwitchData.hpp +4 -2
@@ 40,8 40,10 @@ namespace gui
    class AppsBatteryStatusSwitchData : public BatteryStatusSwitchData
    {
      public:
        AppsBatteryStatusSwitchData(const units::SOC soc, bool chargeState, std::function<void()> returnCallback)
            : BatteryStatusSwitchData{soc, chargeState, true}, returnCallback{returnCallback}
        AppsBatteryStatusSwitchData(const units::SOC soc,
                                    bool chargeState,
                                    std::function<void()> returnCallback = nullptr)
            : BatteryStatusSwitchData{soc, chargeState, true}, returnCallback{std::move(returnCallback)}
        {}

        [[nodiscard]] auto getReturnCallback() const noexcept -> std::function<void()>

M products/BellHybrid/apps/common/include/common/popups/BedtimeNotificationWindow.hpp => products/BellHybrid/apps/common/include/common/popups/BedtimeNotificationWindow.hpp +2 -1
@@ 1,4 1,4 @@
// Copyright (c) 2017-2023, Mudita Sp. z.o.o. All rights reserved.
// Copyright (c) 2017-2024, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#pragma once


@@ 10,6 10,7 @@ namespace app
{
    class ApplicationCommon;
}

namespace gui
{
    class Icon;

M products/BellHybrid/apps/common/include/common/windows/BellFinishedWindow.hpp => products/BellHybrid/apps/common/include/common/windows/BellFinishedWindow.hpp +3 -4
@@ 1,4 1,4 @@
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// Copyright (c) 2017-2024, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#pragma once


@@ 11,7 11,7 @@ namespace gui
{
    namespace window::bell_finished
    {
        constexpr inline auto defaultName = "BellFinishedWindow";
        inline constexpr auto defaultName = "BellFinishedWindow";
    } // namespace window::bell_finished

    class Icon;


@@ 19,7 19,7 @@ namespace gui
    class BellFinishedWindow : public WindowWithTimer
    {
      public:
        explicit BellFinishedWindow(app::ApplicationCommon *app, const std::string &name);
        BellFinishedWindow(app::ApplicationCommon *app, const std::string &name);

      protected:
        void buildInterface() override;


@@ 31,5 31,4 @@ namespace gui
        std::string windowToReturn{};
        BellFinishedWindowData::ExitBehaviour exitBehaviour;
    };

} // namespace gui

M products/BellHybrid/apps/common/src/models/LowBatteryInfoModel.cpp => products/BellHybrid/apps/common/src/models/LowBatteryInfoModel.cpp +0 -1
@@ 14,5 14,4 @@ namespace app
    {
        lowBatteryInfoHandled = true;
    }

} // namespace app

M products/BellHybrid/apps/common/src/options/BellOptionWindow.cpp => products/BellHybrid/apps/common/src/options/BellOptionWindow.cpp +1 -3
@@ 1,4 1,4 @@
// Copyright (c) 2017-2023, Mudita Sp. z.o.o. All rights reserved.
// Copyright (c) 2017-2024, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include "common/options/BellOptionWindow.hpp"


@@ 6,7 6,6 @@
#include "common/options/BellOptionsNavigation.hpp"

#include <messages/OptionsWindow.hpp>
#include <TextFixedSize.hpp>

namespace gui
{


@@ 66,5 65,4 @@ namespace gui

        optionsList->rebuildList(listview::RebuildType::InPlace);
    }

} /* namespace gui */

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

#include <audio/AudioMessage.hpp>
#include <apps-common/popups/Popups.hpp>
#include <apps-common/popups/data/PopupRequestParams.hpp>
#include <common/popups/BedtimeNotificationWindow.hpp>


@@ 71,5 70,4 @@ namespace gui
        }
        return false;
    }

} /* namespace gui */

M products/BellHybrid/apps/common/src/windows/BellFinishedWindow.cpp => products/BellHybrid/apps/common/src/windows/BellFinishedWindow.cpp +1 -3
@@ 1,4 1,4 @@
// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
// Copyright (c) 2017-2024, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include "windows/BellFinishedWindow.hpp"


@@ 10,7 10,6 @@

namespace gui
{

    BellFinishedWindow::BellFinishedWindow(app::ApplicationCommon *app, const std::string &name)
        : WindowWithTimer(app, name)
    {


@@ 78,5 77,4 @@ namespace gui
            }
        }
    }

} // namespace gui

M products/BellHybrid/services/appmgr/IdleHandler.cpp => products/BellHybrid/services/appmgr/IdleHandler.cpp +16 -9
@@ 1,33 1,40 @@
// Copyright (c) 2017-2023, Mudita Sp. z.o.o. All rights reserved.
// Copyright (c) 2017-2024, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include <appmgr/IdleHandler.hpp>
#include <appmgr/messages/IdleTimerMessage.hpp>

#include <service-appmgr/Controller.hpp>
#include <Timers/TimerFactory.hpp>
#include <chrono>

namespace
{
    constexpr auto idleReturnTimerTimeout{std::chrono::minutes{3}};
    constexpr auto idleReturnTimerName{"IdleReturn"};
} // namespace

namespace app::manager
{
    IdleHandler::IdleHandler(sys::Service *serv) : serv{serv}
    {
        idleTimer = sys::TimerFactory::createPeriodicTimer(
            serv, "IdleReturn", idleReturnTimeout, [this](sys::Timer &) { idleTimerCallback(); });
            serv, idleReturnTimerName, idleReturnTimerTimeout, [this]([[maybe_unused]] sys::Timer &timer) {
                idleTimerCallback();
            });
    }

    void IdleHandler::handleStartIdleTimer(sys::Message *request)
    void IdleHandler::handleStartIdleTimer([[maybe_unused]] sys::Message *request)
    {
        idleTimer.restart(idleReturnTimeout);
        idleTimer.restart(idleReturnTimerTimeout);
    }

    void IdleHandler::handleRestartIdleTimer(sys::Message *request)
    void IdleHandler::handleRestartIdleTimer([[maybe_unused]] sys::Message *request)
    {
        if (idleTimer.isActive()) {
            idleTimer.restart(idleReturnTimeout);
            idleTimer.restart(idleReturnTimerTimeout);
        }
    }

    void IdleHandler::handleStopIdleTimer(sys::Message *request)
    void IdleHandler::handleStopIdleTimer([[maybe_unused]] sys::Message *request)
    {
        idleTimer.stop();
    }

M products/BellHybrid/services/appmgr/include/appmgr/IdleHandler.hpp => products/BellHybrid/services/appmgr/include/appmgr/IdleHandler.hpp +1 -6
@@ 7,17 7,12 @@
#include <Service/Message.hpp>
#include <Timers/TimerHandle.hpp>

#include <chrono>

namespace app::manager
{
    constexpr auto idleReturnTimeout = std::chrono::seconds{180};
    using connectFunction            = std::function<bool(const std::type_info &, sys::MessageHandler)>;

    class IdleHandler
    {
      public:
        IdleHandler(sys::Service *serv);
        explicit IdleHandler(sys::Service *serv);

      protected:
        void handleStartIdleTimer(sys::Message *request);