~aleteoryx/muditaos

4ad0f29ab49cde21debe3f98a8b0ba99e3aa585c — Lefucjusz 1 year, 11 months ago 1b37e62
[BH-1898] Fix of GUI freeze after intensive volume change

Fix of the issue that GUI would freeze for
several seconds if volume level was being
changed intensively for a while.
44 files changed, 279 insertions(+), 226 deletions(-)

M harmony_changelog.md
M module-audio/Audio/AudioCommon.hpp
M module-services/service-db/agents/settings/SettingsProxy.cpp
M module-services/service-fileindexer/ServiceFileIndexer.cpp
M module-utils/CrashdumpMetadataStore/CrashdumpMetadataStore.cpp
M module-utils/log/Logger.cpp
M module-vfs/paths/filesystem_paths.cpp
M products/BellHybrid/apps/application-bell-main/windows/BellHomeScreenWindow.cpp
M products/BellHybrid/apps/application-bell-meditation-timer/models/ChimeVolume.cpp
M products/BellHybrid/apps/application-bell-meditation-timer/presenter/SettingsPresenter.cpp
M products/BellHybrid/apps/application-bell-powernap/data/PowerNapListItem.cpp
M products/BellHybrid/apps/application-bell-relaxation/presenter/RelaxationVolumePresenter.cpp
M products/BellHybrid/apps/application-bell-relaxation/presenter/RelaxationVolumePresenter.hpp
M products/BellHybrid/apps/application-bell-relaxation/windows/RelaxationVolumeWindow.cpp
M products/BellHybrid/apps/application-bell-relaxation/windows/RelaxationVolumeWindow.hpp
M products/BellHybrid/apps/application-bell-settings/models/alarm_settings/AlarmSettingsListItemProvider.cpp
M products/BellHybrid/apps/application-bell-settings/models/alarm_settings/AlarmSettingsListItemProvider.hpp
M products/BellHybrid/apps/application-bell-settings/models/alarm_settings/AlarmSettingsModel.cpp
M products/BellHybrid/apps/application-bell-settings/models/alarm_settings/BedtimeSettingsListItemProvider.cpp
M products/BellHybrid/apps/application-bell-settings/models/alarm_settings/BedtimeSettingsListItemProvider.hpp
M products/BellHybrid/apps/application-bell-settings/models/alarm_settings/PrewakeUpListItemProvider.cpp
M products/BellHybrid/apps/application-bell-settings/models/alarm_settings/PrewakeUpListItemProvider.hpp
M products/BellHybrid/apps/application-bell-settings/models/alarm_settings/PrewakeUpSettingsModel.cpp
M products/BellHybrid/apps/application-bell-settings/models/alarm_settings/SettingsListItemProvider.cpp
M products/BellHybrid/apps/application-bell-settings/models/alarm_settings/SettingsListItemProvider.hpp
M products/BellHybrid/apps/application-bell-settings/models/alarm_settings/SnoozeListItemProvider.cpp
M products/BellHybrid/apps/application-bell-settings/models/alarm_settings/SnoozeListItemProvider.hpp
M products/BellHybrid/apps/application-bell-settings/models/alarm_settings/SnoozeSettingsModel.cpp
M products/BellHybrid/apps/application-bell-settings/presenter/BedtimeSettingsPresenter.cpp
M products/BellHybrid/apps/application-bell-settings/presenter/alarm_settings/AlarmSettingsPresenter.cpp
M products/BellHybrid/apps/application-bell-settings/presenter/alarm_settings/PrewakeUpPresenter.cpp
M products/BellHybrid/apps/application-bell-settings/presenter/alarm_settings/SnoozePresenter.cpp
M products/BellHybrid/apps/application-bell-settings/windows/BellSettingsLayoutWindow.cpp
M products/BellHybrid/apps/common/include/common/models/AbstractAudioModel.hpp
M products/BellHybrid/apps/common/include/common/models/AbstractSettingsModel.hpp
M products/BellHybrid/apps/common/include/common/models/AudioModel.hpp
M products/BellHybrid/apps/common/include/common/widgets/list_items/details.hpp
M products/BellHybrid/apps/common/src/AudioModel.cpp
M products/BellHybrid/apps/common/src/layouts/ShortcutsLayoutClassic.cpp
M products/BellHybrid/apps/common/src/models/BedtimeModel.cpp
M products/BellHybrid/apps/common/src/widgets/ProgressTimerWithSnoozeTimer.cpp
M products/BellHybrid/services/audio/ServiceAudio.cpp
M products/BellHybrid/services/audio/include/audio/AudioMessage.hpp
M products/BellHybrid/services/audio/include/audio/ServiceAudio.hpp
M harmony_changelog.md => harmony_changelog.md +2 -1
@@ 4,7 4,8 @@

### Fixed
* Fixed BIWIN eMMC memory errors
* Fixed freeze after changing Relaxation volume intensively
* Fixed device freeze after changing Relaxation volume intensively
* Fixed UI freeze after changing any volume intensively

### Added
* Added new 32px and 170px fonts

M module-audio/Audio/AudioCommon.hpp => module-audio/Audio/AudioCommon.hpp +6 -0
@@ 82,6 82,12 @@ namespace audio
        Enable
    };

    enum class VolumeUpdateType
    {
        UpdateDB,
        SkipUpdateDB
    };

    /// Used to describe audio operations
    using Context = std::pair<Profile::Type, PlaybackType>;


M module-services/service-db/agents/settings/SettingsProxy.cpp => module-services/service-db/agents/settings/SettingsProxy.cpp +7 -12
@@ 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 <service-db/EntryPath.hpp>


@@ 12,7 12,6 @@

namespace settings
{

    SettingsProxy::SettingsProxy(const service::ServiceProxy &interface) : service::ServiceProxy(interface)
    {}



@@ 58,25 57,21 @@ namespace settings
        }
    }

    template <typename T, typename... Args>
    auto message(sys::BusProxy &bus, Args... args)
    {
        bus.sendUnicast(std::make_shared<T>(args...), service::name::db);
    }

    void SettingsProxy::registerValueChange(EntryPath path)
    {
        message<settings::Messages::RegisterOnVariableChange>(getService()->bus, std::move(path));
        auto msg = std::make_shared<Messages::RegisterOnVariableChange>(std::move(path));
        getService()->bus.sendUnicast(std::move(msg), service::name::db);
    }

    void SettingsProxy::unregisterValueChange(EntryPath path)
    {
        message<settings::Messages::UnregisterOnVariableChange>(getService()->bus, std::move(path));
        auto msg = std::make_shared<Messages::UnregisterOnVariableChange>(std::move(path));
        getService()->bus.sendUnicast(std::move(msg), service::name::db);
    }

    void SettingsProxy::setValue(const EntryPath &path, const std::string &value)
    {
        message<settings::Messages::SetVariable>(getService()->bus, path, value);
        auto msg = std::make_shared<Messages::SetVariable>(path, value);
        getService()->bus.sendUnicast(std::move(msg), service::name::db);
    }

} // namespace settings

M module-services/service-fileindexer/ServiceFileIndexer.cpp => module-services/service-fileindexer/ServiceFileIndexer.cpp +2 -4
@@ 1,8 1,7 @@
// 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 <service-fileindexer/ServiceFileIndexer.hpp>

#include <service-fileindexer/ServiceFileIndexerName.hpp>

#include <log/log.hpp>


@@ 10,12 9,11 @@

namespace
{
    inline constexpr auto fileIndexerServiceStackSize = 1024 * 5;
    constexpr auto fileIndexerServiceStackSize = 1024 * 5;
} // namespace

namespace service
{

    ServiceFileIndexer::ServiceFileIndexer(const std::vector<std::string> &paths)
        : sys::Service{service::name::file_indexer, "", fileIndexerServiceStackSize}, mStartupIndexer{paths}
    {

M module-utils/CrashdumpMetadataStore/CrashdumpMetadataStore.cpp => module-utils/CrashdumpMetadataStore/CrashdumpMetadataStore.cpp +7 -7
@@ 1,16 1,16 @@
// 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 "CrashdumpMetadataStore.hpp"

namespace
{
    inline constexpr auto separator                 = "_";
    inline constexpr auto defaultSerialNumberLength = 13;
    inline constexpr auto defaultCommitHashLength   = 8;
    inline constexpr auto defaultProductName        = "unknown";
    inline constexpr auto defaultOsVersion          = "0.0.0";
    inline constexpr auto defaultFillValue          = '0';
    constexpr auto separator                 = "_";
    constexpr auto defaultSerialNumberLength = 13;
    constexpr auto defaultCommitHashLength   = 8;
    constexpr auto defaultProductName        = "unknown";
    constexpr auto defaultOsVersion          = "0.0.0";
    constexpr auto defaultFillValue          = '0';
} // namespace

namespace Store

M module-utils/log/Logger.cpp => module-utils/log/Logger.cpp +6 -6
@@ 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 "Logger.hpp"


@@ 11,11 11,11 @@

namespace
{
    inline constexpr int statusSuccess         = 1;
    inline constexpr auto streamBufferSize     = 64 * 1024;
    inline constexpr auto logFileNamePrefix    = "MuditaOS";
    inline constexpr auto logFileNameExtension = ".log";
    inline constexpr auto logFileNameSeparator = "_";
    constexpr int statusSuccess         = 1;
    constexpr auto streamBufferSize     = 64 * 1024;
    constexpr auto logFileNamePrefix    = "MuditaOS";
    constexpr auto logFileNameExtension = ".log";
    constexpr auto logFileNameSeparator = "_";
} // namespace

namespace Log

M module-vfs/paths/filesystem_paths.cpp => module-vfs/paths/filesystem_paths.cpp +13 -13
@@ 1,21 1,21 @@
// 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 <purefs/filesystem_paths.hpp>

namespace
{
    constexpr inline auto PATH_SYSTEM      = "/system";
    constexpr inline auto PATH_USER        = "/user";
    constexpr inline auto PATH_CONF        = "/mfgconf";
    constexpr inline auto PATH_DB          = "db";
    constexpr inline auto PATH_LOGS        = "log";
    constexpr inline auto PATH_CRASH_DUMPS = "crash_dumps";
    constexpr inline auto PATH_USER_MEDIA  = "media";
    constexpr inline auto PATH_TMP         = "temp";
    constexpr inline auto PATH_ASSETS      = "assets";
    constexpr inline auto PATH_DATA        = "data";
    constexpr inline auto PATH_VAR         = "var";
    constexpr auto PATH_SYSTEM      = "/system";
    constexpr auto PATH_USER        = "/user";
    constexpr auto PATH_CONF        = "/mfgconf";
    constexpr auto PATH_DB          = "db";
    constexpr auto PATH_LOGS        = "log";
    constexpr auto PATH_CRASH_DUMPS = "crash_dumps";
    constexpr auto PATH_USER_MEDIA  = "media";
    constexpr auto PATH_TMP         = "temp";
    constexpr auto PATH_ASSETS      = "assets";
    constexpr auto PATH_DATA        = "data";
    constexpr auto PATH_VAR         = "var";
} // namespace

namespace purefs


@@ 76,10 76,10 @@ namespace purefs
        {
            return getSystemDiskPath() / PATH_DATA;
        }

        std::filesystem::path getSystemVarDirPath() noexcept
        {
            return getSystemDiskPath() / PATH_VAR;
        }

    } // namespace dir
} // namespace purefs

M products/BellHybrid/apps/application-bell-main/windows/BellHomeScreenWindow.cpp => products/BellHybrid/apps/application-bell-main/windows/BellHomeScreenWindow.cpp +2 -3
@@ 18,8 18,8 @@

namespace
{
    inline constexpr auto snoozeTimerName = "SnoozeTimer";
    inline constexpr std::chrono::seconds timerTick{1};
    constexpr auto snoozeTimerName = "SnoozeTimer";
    constexpr std::chrono::seconds timerTick{1};
} // namespace

namespace gui


@@ 196,5 196,4 @@ namespace gui
            currentLayout->setQuoteText(quoteContent, quoteAuthor);
        }
    }

} // namespace gui

M products/BellHybrid/apps/application-bell-meditation-timer/models/ChimeVolume.cpp => products/BellHybrid/apps/application-bell-meditation-timer/models/ChimeVolume.cpp +7 -8
@@ 1,16 1,20 @@
// 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

#include "ChimeVolume.hpp"

namespace app::meditation::models
{
    ChimeVolume::ChimeVolume(AbstractAudioModel &audioModel) : audioModel{audioModel}
    {
        defaultValue = audioModel.getVolume(AbstractAudioModel::PlaybackType::Meditation).value_or(0);
    }

    void ChimeVolume::setValue(std::uint8_t value)
    {
        defaultValue = value;
        audioModel.setVolume(value, AbstractAudioModel::PlaybackType::Meditation, {});
        audioModel.setVolume(value, AbstractAudioModel::PlaybackType::Meditation);
    }

    std::uint8_t ChimeVolume::getValue() const
    {
        return audioModel.getVolume(AbstractAudioModel::PlaybackType::Meditation).value_or(0);


@@ 20,9 24,4 @@ namespace app::meditation::models
    {
        setValue(defaultValue);
    }

    ChimeVolume::ChimeVolume(AbstractAudioModel &audioModel) : audioModel{audioModel}
    {
        defaultValue = audioModel.getVolume(AbstractAudioModel::PlaybackType::Meditation).value_or(0);
    }
} // namespace app::meditation::models

M products/BellHybrid/apps/application-bell-meditation-timer/presenter/SettingsPresenter.cpp => products/BellHybrid/apps/application-bell-meditation-timer/presenter/SettingsPresenter.cpp +10 -6
@@ 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 "SettingsPresenter.hpp"


@@ 51,7 51,6 @@ namespace app::list_items
            bottomText->setRichText(utils::language::getCorrectSecondsNumeralForm(value));
        }
    };

} // namespace app::list_items

namespace app::meditation


@@ 86,16 85,17 @@ namespace app::meditation
        listItemsProvider =
            std::make_shared<BellListItemProvider>(BellListItemProvider::Items{startDelay, chimeInterval, chimeVolume});

        auto playSound = [this]() {
        auto playSound = [this, chimeVolume]() {
            this->audioModel.setVolume(chimeVolume->value(), AbstractAudioModel::PlaybackType::Meditation);
            this->audioModel.play(getMeditationAudioPath(), AbstractAudioModel::PlaybackType::Meditation, {});
        };

        chimeVolume->onEnter = playSound;

        chimeVolume->onExit = [this]() { stopSound(); };

        chimeVolume->set_on_value_change_cb([this, playSound](const auto &val) {
            this->audioModel.setVolume(val, AbstractAudioModel::PlaybackType::Meditation, {});
            this->audioModel.setVolume(
                val, AbstractAudioModel::PlaybackType::Meditation, audio::VolumeUpdateType::SkipUpdateDB);
            if (this->audioModel.hasPlaybackFinished()) {
                playSound();
            }


@@ 105,26 105,31 @@ namespace app::meditation
            item->setValue();
        }
    }

    void SettingsPresenter::loadData()
    {
        for (auto &item : listItemsProvider->getListItems()) {
            item->setValue();
        }
    }

    void SettingsPresenter::saveData()
    {
        for (auto &item : listItemsProvider->getListItems()) {
            item->getValue();
        }
    }

    auto SettingsPresenter::getPagesProvider() const -> std::shared_ptr<gui::ListItemProvider>
    {
        return listItemsProvider;
    }

    void SettingsPresenter::eraseProviderData()
    {
        listItemsProvider->clearData();
    }

    void SettingsPresenter::exitWithSave()
    {
        saveData();


@@ 142,5 147,4 @@ namespace app::meditation
        chimeVolumeModel.restoreDefault();
        eraseProviderData();
    }

} // namespace app::meditation

M products/BellHybrid/apps/application-bell-powernap/data/PowerNapListItem.cpp => products/BellHybrid/apps/application-bell-powernap/data/PowerNapListItem.cpp +6 -5
@@ 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 "PowerNapListItem.hpp"


@@ 6,12 6,14 @@
#include "data/PowerNapStyle.hpp"

#include <common/LanguageUtils.hpp>

namespace
{
    inline constexpr auto spinnerMax  = 180U;
    inline constexpr auto spinnerMin  = 1U;
    inline constexpr auto spinnerStep = 1U;
    constexpr auto spinnerMax  = 180U;
    constexpr auto spinnerMin  = 1U;
    constexpr auto spinnerStep = 1U;
} // namespace

namespace gui
{
    PowerNapListItem::PowerNapListItem()


@@ 92,5 94,4 @@ namespace gui
        body->setArrowVisible(BellBaseLayout::Arrow::Left, not isMin);
        body->setArrowVisible(BellBaseLayout::Arrow::Right, not isMax);
    }

} // namespace gui

M products/BellHybrid/apps/application-bell-relaxation/presenter/RelaxationVolumePresenter.cpp => products/BellHybrid/apps/application-bell-relaxation/presenter/RelaxationVolumePresenter.cpp +9 -2
@@ 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 "RelaxationVolumePresenter.hpp"


@@ 15,8 15,15 @@ namespace app::relaxation

    void RelaxationVolumePresenter::setVolume(AbstractAudioModel::Volume volume)
    {
        audioModel.setVolume(volume, AbstractAudioModel::PlaybackType::Multimedia, {});
        audioModel.setVolume(
            volume, AbstractAudioModel::PlaybackType::Multimedia, audio::VolumeUpdateType::SkipUpdateDB);
    }

    void RelaxationVolumePresenter::saveVolume(AbstractAudioModel::Volume volume)
    {
        audioModel.setVolume(volume, AbstractAudioModel::PlaybackType::Multimedia);
    }

    AbstractAudioModel::Volume RelaxationVolumePresenter::getVolume()
    {
        return audioModel.getVolume(AbstractAudioModel::PlaybackType::Multimedia).value_or(defaultVolume);

M products/BellHybrid/apps/application-bell-relaxation/presenter/RelaxationVolumePresenter.hpp => products/BellHybrid/apps/application-bell-relaxation/presenter/RelaxationVolumePresenter.hpp +5 -2
@@ 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


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

namespace app::relaxation
{
    using VolumeData = struct VolumeData


@@ 24,12 25,13 @@ namespace app::relaxation
        virtual ~AbstractRelaxationVolumePresenter()              = default;
        virtual VolumeData getVolumeData()                        = 0;
        virtual void setVolume(AbstractAudioModel::Volume volume) = 0;
        virtual void saveVolume(AbstractAudioModel::Volume volume) = 0;
        virtual AbstractAudioModel::Volume getVolume()            = 0;
    };

    class RelaxationVolumePresenter : public AbstractRelaxationVolumePresenter
    {
        constexpr static struct VolumeData volumeData
        static constexpr struct VolumeData volumeData
        {
            AbstractAudioModel::minVolume, AbstractAudioModel::maxVolume, 1
        };


@@ 39,6 41,7 @@ namespace app::relaxation

        VolumeData getVolumeData() override;
        void setVolume(AbstractAudioModel::Volume volume) override;
        void saveVolume(AbstractAudioModel::Volume volume) override;
        AbstractAudioModel::Volume getVolume() override;

      public:

M products/BellHybrid/apps/application-bell-relaxation/windows/RelaxationVolumeWindow.cpp => products/BellHybrid/apps/application-bell-relaxation/windows/RelaxationVolumeWindow.cpp +14 -6
@@ 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 "RelaxationVolumeWindow.hpp"


@@ 56,7 56,7 @@ namespace gui
        progress->setMaximum(arcProgressSteps);
        progress->setValue(presenter->getVolume());

        auto data = presenter->getVolumeData();
        const auto data = presenter->getVolumeData();
        spinner   = new U8IntegerSpinner({static_cast<U8IntegerSpinner::value_type>(data.min),
                                        static_cast<U8IntegerSpinner::value_type>(data.max),
                                        static_cast<U8IntegerSpinner::value_type>(data.step)},


@@ 78,15 78,23 @@ namespace gui
    bool RelaxationVolumeWindow::onInput(const InputEvent &inputEvent)
    {
        if (inputEvent.isShortRelease(KeyCode::KEY_ENTER) || inputEvent.isShortRelease(KeyCode::KEY_RF)) {
            presenter->saveVolume(spinner->value());
            application->returnToPreviousWindow();
            return true;
        }

        resetTimer();
        auto data              = presenter->getVolumeData();
        const auto data          = presenter->getVolumeData();
        const auto ret         = body->onInput(inputEvent);
        const auto selectedVal = spinner->value();
        progress->setValue(presenter->getVolume());
        body->setMinMaxArrowsVisibility(selectedVal == data.min, selectedVal == data.max);
        const auto selectedValue = spinner->value();
        progress->setValue(selectedValue);
        body->setMinMaxArrowsVisibility(selectedValue == data.min, selectedValue == data.max);
        return ret;
    }

    void RelaxationVolumeWindow::onClose(CloseReason reason)
    {
        presenter->saveVolume(spinner->value());
        WindowWithTimer::onClose(reason);
    }
} // namespace gui

M products/BellHybrid/apps/application-bell-relaxation/windows/RelaxationVolumeWindow.hpp => products/BellHybrid/apps/application-bell-relaxation/windows/RelaxationVolumeWindow.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


@@ 28,5 28,6 @@ namespace gui

        void buildInterface() override;
        bool onInput(const gui::InputEvent &inputEvent) override;
        void onClose(CloseReason reason) override;
    };
} // namespace gui

M products/BellHybrid/apps/application-bell-settings/models/alarm_settings/AlarmSettingsListItemProvider.cpp => products/BellHybrid/apps/application-bell-settings/models/alarm_settings/AlarmSettingsListItemProvider.cpp +8 -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 "BellSettingsStyle.hpp"


@@ 53,7 53,7 @@ namespace app::bell_settings
        constexpr auto volumeStep = 1U;
        constexpr auto volumeMin  = AbstractAudioModel::minVolume;
        constexpr auto volumeMax  = AbstractAudioModel::maxVolume;
        auto alarmVolume          = new list_items::NumericWithBar(
        alarmVolume               = new list_items::NumericWithBar(
            list_items::NumericWithBar::spinner_type::range{volumeMin, volumeMax, volumeStep},
            settingsModel.getAlarmVolume(),
            volumeMax,


@@ 68,7 68,7 @@ namespace app::bell_settings
                onVolumeEnter(alarmTone->value());
            }
        };
        alarmVolume->onExit = [this, alarmVolume]() {
        alarmVolume->onExit = [this]() {
            if (onVolumeExit) {
                onVolumeExit(alarmVolume->value());
            }


@@ 123,4 123,9 @@ namespace app::bell_settings
            item->deleteByList = false;
        }
    }

    auto AlarmSettingsListItemProvider::getCurrentVolume() -> std::uint8_t
    {
        return alarmVolume->value();
    }
} // namespace app::bell_settings

M products/BellHybrid/apps/application-bell-settings/models/alarm_settings/AlarmSettingsListItemProvider.hpp => products/BellHybrid/apps/application-bell-settings/models/alarm_settings/AlarmSettingsListItemProvider.hpp +9 -2
@@ 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

#pragma once


@@ 7,6 7,11 @@
#include <common/models/AbstractAlarmSettingsModel.hpp>
#include <common/models/AbstractSettingsModel.hpp>

namespace app::list_items
{
    class NumericWithBar;
}

namespace app::bell_settings
{
    class AbstractFrontlightModel;


@@ 15,10 20,12 @@ namespace app::bell_settings
      public:
        AlarmSettingsListItemProvider(AbstractAlarmSettingsModel &settingsModel, std::vector<UTF8> alarmToneRange);

        auto getCurrentVolume() -> std::uint8_t;

      private:
        void buildListItems(std::vector<UTF8> alarmTonesRange);

        AbstractAlarmSettingsModel &settingsModel;
        app::list_items::NumericWithBar *alarmVolume{nullptr};
    };

} // namespace app::bell_settings

M products/BellHybrid/apps/application-bell-settings/models/alarm_settings/AlarmSettingsModel.cpp => products/BellHybrid/apps/application-bell-settings/models/alarm_settings/AlarmSettingsModel.cpp +2 -2
@@ 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/models/AlarmSettingsModel.hpp>


@@ 30,7 30,7 @@ namespace app::bell_settings

    void AlarmVolumeModel::setValue(std::uint8_t value)
    {
        audioModel.setVolume(value, AbstractAudioModel::PlaybackType::Alarm, {});
        audioModel.setVolume(value, AbstractAudioModel::PlaybackType::Alarm);
    }

    std::uint8_t AlarmVolumeModel::getValue() const

M products/BellHybrid/apps/application-bell-settings/models/alarm_settings/BedtimeSettingsListItemProvider.cpp => products/BellHybrid/apps/application-bell-settings/models/alarm_settings/BedtimeSettingsListItemProvider.cpp +12 -8
@@ 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 "BedtimeSettingsListItemProvider.hpp"


@@ 15,7 15,7 @@ namespace app::bell_settings

    BedtimeSettingsListItemProvider::BedtimeSettingsListItemProvider(std::shared_ptr<AbstractBedtimeModel> model,
                                                                     std::vector<UTF8> chimeToneRange)
        : model{model}
        : model{std::move(model)}
    {
        buildListItems(std::move(chimeToneRange));
    }


@@ 47,32 47,36 @@ namespace app::bell_settings
        constexpr auto volumeStep = 1U;
        constexpr auto volumeMin  = AbstractAudioModel::minVolume;
        constexpr auto volumeMax  = AbstractAudioModel::maxVolume;
        auto volume               = new list_items::NumericWithBar(
        bedtimeVolume             = new list_items::NumericWithBar(
            list_items::NumericWithBar::spinner_type::range{volumeMin, volumeMax, volumeStep},
            model->getBedtimeVolume(),
            volumeMax,
            utils::translate("app_bell_settings_bedtime_settings_volume"));
        volume->set_on_value_change_cb([this](const auto &val) {
        bedtimeVolume->set_on_value_change_cb([this](const auto &val) {
            if (onVolumeChange) {
                onVolumeChange(val);
            }
        });

        volume->onEnter = [this, chimeTone]() {
        bedtimeVolume->onEnter = [this, chimeTone]() {
            if (onVolumeEnter) {
                onVolumeEnter(chimeTone->value());
            }
        };

        volume->onExit = [this, volume]() {
        bedtimeVolume->onExit = [this]() {
            if (onVolumeExit) {
                onVolumeExit(volume->value());
                onVolumeExit(bedtimeVolume->value());
            }
        };
        internalData.emplace_back(volume);
        internalData.emplace_back(bedtimeVolume);
        for (auto item : internalData) {
            item->deleteByList = false;
        }
    }

    auto BedtimeSettingsListItemProvider::getCurrentVolume() -> std::uint8_t
    {
        return bedtimeVolume->value();
    }
} // namespace app::bell_settings

M products/BellHybrid/apps/application-bell-settings/models/alarm_settings/BedtimeSettingsListItemProvider.hpp => products/BellHybrid/apps/application-bell-settings/models/alarm_settings/BedtimeSettingsListItemProvider.hpp +12 -5
@@ 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


@@ 9,17 9,24 @@
#include <Service/Service.hpp>
#include "SettingsListItemProvider.hpp"

namespace app::list_items
{
    class NumericWithBar;
}

namespace app::bell_settings
{
    class BedtimeSettingsListItemProvider : public SettingsListItemProvider
    {
      public:
        explicit BedtimeSettingsListItemProvider(std::shared_ptr<AbstractBedtimeModel> model,
                                                 std::vector<UTF8> chimeToneRange);
        BedtimeSettingsListItemProvider(std::shared_ptr<AbstractBedtimeModel> model, std::vector<UTF8> chimeToneRange);

        auto getCurrentVolume() -> std::uint8_t;

      private:
        void buildListItems(std::vector<UTF8> bedtimeToneRange);
        std::shared_ptr<AbstractBedtimeModel> &model;
    };

        std::shared_ptr<AbstractBedtimeModel> model;
        app::list_items::NumericWithBar *bedtimeVolume{nullptr};
    };
} // namespace app::bell_settings

M products/BellHybrid/apps/application-bell-settings/models/alarm_settings/PrewakeUpListItemProvider.cpp => products/BellHybrid/apps/application-bell-settings/models/alarm_settings/PrewakeUpListItemProvider.cpp +12 -7
@@ 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 "PrewakeUpListItemProvider.hpp"


@@ 74,29 74,29 @@ namespace app::bell_settings
        constexpr auto volumeStep = 1U;
        constexpr auto volumeMin  = AbstractAudioModel::minVolume;
        constexpr auto volumeMax  = AbstractAudioModel::maxVolume;
        auto volume               = new list_items::NumericWithBar(
        prewakeUpVolume           = new list_items::NumericWithBar(
            list_items::NumericWithBar::spinner_type::range{volumeMin, volumeMax, volumeStep},
            settingsModel.getChimeVolume(),
            volumeMax,
            utils::translate("app_bell_settings_alarm_settings_prewake_up_chime_volume"));
        volume->set_on_value_change_cb([this](const auto &val) {
        prewakeUpVolume->set_on_value_change_cb([this](const auto &val) {
            if (onVolumeChange) {
                onVolumeChange(val);
            }
        });

        volume->onEnter = [this, chimeTone]() {
        prewakeUpVolume->onEnter = [this, chimeTone]() {
            if (onVolumeEnter) {
                onVolumeEnter(chimeTone->value());
            }
        };

        volume->onExit = [this, volume]() {
        prewakeUpVolume->onExit = [this]() {
            if (onVolumeExit) {
                onVolumeExit(volume->value());
                onVolumeExit(prewakeUpVolume->value());
            }
        };
        internalData.emplace_back(volume);
        internalData.emplace_back(prewakeUpVolume);

        auto lightDuration = new list_items::NumberWithSuffix(
            list_items::NumberWithSuffix::spinner_type::range{0, 5, 10, 15},


@@ 151,4 151,9 @@ namespace app::bell_settings
            item->deleteByList = false;
        }
    }

    auto PrewakeUpListItemProvider::getCurrentVolume() -> std::uint8_t
    {
        return prewakeUpVolume->value();
    }
} // namespace app::bell_settings

M products/BellHybrid/apps/application-bell-settings/models/alarm_settings/PrewakeUpListItemProvider.hpp => products/BellHybrid/apps/application-bell-settings/models/alarm_settings/PrewakeUpListItemProvider.hpp +9 -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


@@ 7,6 7,11 @@
#include "AbstractPrewakeUpSettingsModel.hpp"
#include <common/models/AbstractSettingsModel.hpp>

namespace app::list_items
{
    class NumericWithBar;
}

namespace app::bell_settings
{
    class AbstractFrontlightModel;


@@ 15,9 20,12 @@ namespace app::bell_settings
      public:
        PrewakeUpListItemProvider(AbstractPrewakeUpSettingsModel &settingsModel, std::vector<UTF8> chimeToneRange);

        auto getCurrentVolume() -> std::uint8_t;

      private:
        void buildListItems(std::vector<UTF8> preWakeupToneRange);

        AbstractPrewakeUpSettingsModel &settingsModel;
        app::list_items::NumericWithBar *prewakeUpVolume{nullptr};
    };
} // namespace app::bell_settings

M products/BellHybrid/apps/application-bell-settings/models/alarm_settings/PrewakeUpSettingsModel.cpp => products/BellHybrid/apps/application-bell-settings/models/alarm_settings/PrewakeUpSettingsModel.cpp +2 -2
@@ 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 <models/alarm_settings/PrewakeUpSettingsModel.hpp>


@@ 35,7 35,7 @@ namespace app::bell_settings

    void PrewakeUpChimeVolumeModel::setValue(std::uint8_t value)
    {
        audioModel.setVolume(value, AbstractAudioModel::PlaybackType::PreWakeup, {});
        audioModel.setVolume(value, AbstractAudioModel::PlaybackType::PreWakeup);
    }

    std::uint8_t PrewakeUpChimeVolumeModel::getValue() const

M products/BellHybrid/apps/application-bell-settings/models/alarm_settings/SettingsListItemProvider.cpp => products/BellHybrid/apps/application-bell-settings/models/alarm_settings/SettingsListItemProvider.cpp +6 -2
@@ 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

#include "SettingsListItemProvider.hpp"


@@ 6,28 6,32 @@

namespace app::bell_settings
{

    std::vector<gui::BellSideListItemWithCallbacks *> SettingsListItemProvider::getListItems()
    {
        return internalData;
    }

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

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

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

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

    void SettingsListItemProvider::clearData()
    {
        list->reset();

M products/BellHybrid/apps/application-bell-settings/models/alarm_settings/SettingsListItemProvider.hpp => products/BellHybrid/apps/application-bell-settings/models/alarm_settings/SettingsListItemProvider.hpp +3 -5
@@ 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

#pragma once


@@ 9,14 9,13 @@

namespace app::bell_settings
{

    class SettingsListItemProvider : public app::InternalModel<gui::BellSideListItemWithCallbacks *>,
                                     public gui::ListItemProvider
    {
      public:
        /// Val contains currently chosen tone
        using ToneCallback = std::function<void(const UTF8 &val)>;
        /// Val contains currently chosen volume(1-10 range)
        /// Val contains currently chosen volume (1-10 range)
        using VolumeCallback      = std::function<void(const uint32_t &val)>;
        using VolumeEnterCallback = ToneCallback;
        using FrontlightCallback      = std::function<void(const frontlight_utils::Brightness &val)>;


@@ 25,7 24,7 @@ namespace app::bell_settings

        std::vector<gui::BellSideListItemWithCallbacks *> getListItems();

        auto requestRecords(uint32_t offset, uint32_t limit) -> void override;
        auto requestRecords(std::uint32_t offset, std::uint32_t limit) -> void override;

        [[nodiscard]] auto getItem(gui::Order order) -> gui::ListItem * override;



@@ 49,5 48,4 @@ namespace app::bell_settings
        FrontlightExitCallback onFrontlightExit;
        FrontlightCallback onFrontlightChange;
    };

} // namespace app::bell_settings

M products/BellHybrid/apps/application-bell-settings/models/alarm_settings/SnoozeListItemProvider.cpp => products/BellHybrid/apps/application-bell-settings/models/alarm_settings/SnoozeListItemProvider.cpp +8 -6
@@ 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 "SnoozeListItemProvider.hpp"


@@ 45,9 45,7 @@ namespace app::bell_settings
        if (chimeInterval >= range.back()) {
            return range.back();
        }
        else {
            return chimeInterval;
        }
        return chimeInterval;
    }

    SnoozeListItemProvider::SnoozeListItemProvider(AbstractSnoozeSettingsModel &model,


@@ 146,7 144,7 @@ namespace app::bell_settings
        constexpr auto volumeStep = 1U;
        constexpr auto volumeMin  = AbstractAudioModel::minVolume;
        constexpr auto volumeMax  = AbstractAudioModel::maxVolume;
        auto snoozeChimeVolume    = new list_items::NumericWithBar(
        snoozeChimeVolume         = new list_items::NumericWithBar(
            list_items::NumericWithBar::spinner_type::range{volumeMin, volumeMax, volumeStep},
            model.getSnoozeChimeVolume(),
            volumeMax,


@@ 163,7 161,7 @@ namespace app::bell_settings
            }
        };

        snoozeChimeVolume->onExit = [this, snoozeChimeVolume]() {
        snoozeChimeVolume->onExit = [this]() {
            if (onVolumeExit) {
                onVolumeExit(snoozeChimeVolume->value());
            }


@@ 176,4 174,8 @@ namespace app::bell_settings
        }
    }

    auto SnoozeListItemProvider::getCurrentVolume() -> std::uint8_t
    {
        return snoozeChimeVolume->value();
    }
} // namespace app::bell_settings

M products/BellHybrid/apps/application-bell-settings/models/alarm_settings/SnoozeListItemProvider.hpp => products/BellHybrid/apps/application-bell-settings/models/alarm_settings/SnoozeListItemProvider.hpp +9 -2
@@ 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


@@ 6,6 6,11 @@
#include "SettingsListItemProvider.hpp"
#include "AbstractSnoozeSettingsModel.hpp"

namespace app::list_items
{
    class NumericWithBar;
}

namespace app::bell_settings
{
    class SnoozeListItemProvider : public SettingsListItemProvider


@@ 13,10 18,12 @@ namespace app::bell_settings
      public:
        SnoozeListItemProvider(AbstractSnoozeSettingsModel &model, std::vector<UTF8> chimeTonesRange);

        auto getCurrentVolume() -> std::uint8_t;

      private:
        void buildListItems(std::vector<UTF8> chimeTonesRange);

        AbstractSnoozeSettingsModel &model;
        app::list_items::NumericWithBar *snoozeChimeVolume{nullptr};
    };

} // namespace app::bell_settings

M products/BellHybrid/apps/application-bell-settings/models/alarm_settings/SnoozeSettingsModel.cpp => products/BellHybrid/apps/application-bell-settings/models/alarm_settings/SnoozeSettingsModel.cpp +4 -3
@@ 1,8 1,7 @@
// 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 <models/alarm_settings/SnoozeSettingsModel.hpp>

#include <db/SystemSettings.hpp>

namespace


@@ 73,17 72,19 @@ namespace app::bell_settings

    void SnoozeChimeVolumeModel::setValue(std::uint8_t value)
    {
        audioModel.setVolume(value, AbstractAudioModel::PlaybackType::Snooze, {});
        audioModel.setVolume(value, AbstractAudioModel::PlaybackType::Snooze);
    }

    std::uint8_t SnoozeChimeVolumeModel::getValue() const
    {
        return defaultValue;
    }

    SnoozeChimeVolumeModel::SnoozeChimeVolumeModel(AbstractAudioModel &audioModel) : audioModel{audioModel}
    {
        defaultValue = audioModel.getVolume(AbstractAudioModel::PlaybackType::Snooze).value_or(0);
    }

    void SnoozeChimeVolumeModel::restoreDefault()
    {
        setValue(defaultValue);

M products/BellHybrid/apps/application-bell-settings/presenter/BedtimeSettingsPresenter.cpp => products/BellHybrid/apps/application-bell-settings/presenter/BedtimeSettingsPresenter.cpp +4 -2
@@ 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

#include "BedtimeSettingsPresenter.hpp"


@@ 14,6 14,7 @@ namespace app::bell_settings
    {
        auto playSound = [this](const UTF8 &val) {
            currentSoundPath = val;
            this->audioModel.setVolume(this->provider->getCurrentVolume(), AbstractAudioModel::PlaybackType::Bedtime);
            this->audioModel.play(this->soundsRepository->titleToPath(currentSoundPath).value_or(""),
                                  AbstractAudioModel::PlaybackType::Bedtime,
                                  {});


@@ 27,7 28,8 @@ namespace app::bell_settings
        this->provider->onVolumeEnter  = playSound;
        this->provider->onVolumeExit   = [this](const auto &) { this->stopSound(); };
        this->provider->onVolumeChange = [this, playSound](const auto &val) {
            this->audioModel.setVolume(val, AbstractAudioModel::PlaybackType::Bedtime, {});
            this->audioModel.setVolume(
                val, AbstractAudioModel::PlaybackType::Bedtime, audio::VolumeUpdateType::SkipUpdateDB);
            if (this->audioModel.hasPlaybackFinished()) {
                playSound(currentSoundPath);
            }

M products/BellHybrid/apps/application-bell-settings/presenter/alarm_settings/AlarmSettingsPresenter.cpp => products/BellHybrid/apps/application-bell-settings/presenter/alarm_settings/AlarmSettingsPresenter.cpp +4 -2
@@ 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 "AlarmSettingsPresenter.hpp"


@@ 16,6 16,7 @@ namespace app::bell_settings
    {

        auto playSound = [this](const UTF8 &val) {
            this->audioModel.setVolume(this->provider->getCurrentVolume(), AbstractAudioModel::PlaybackType::Alarm);
            this->audioModel.play(
                this->soundsRepository->titleToPath(val).value_or(""), AbstractAudioModel::PlaybackType::Alarm, {});
        };


@@ 28,7 29,8 @@ namespace app::bell_settings
        this->provider->onVolumeEnter  = playSound;
        this->provider->onVolumeExit   = [this](const auto &) { stopSound(); };
        this->provider->onVolumeChange = [this](const auto &val) {
            this->audioModel.setVolume(val, AbstractAudioModel::PlaybackType::Alarm, {});
            this->audioModel.setVolume(
                val, AbstractAudioModel::PlaybackType::Alarm, audio::VolumeUpdateType::SkipUpdateDB);
        };

        auto setBrightness = [this](const auto &brightness) {

M products/BellHybrid/apps/application-bell-settings/presenter/alarm_settings/PrewakeUpPresenter.cpp => products/BellHybrid/apps/application-bell-settings/presenter/alarm_settings/PrewakeUpPresenter.cpp +4 -2
@@ 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 "PrewakeUpPresenter.hpp"


@@ 16,6 16,7 @@ namespace app::bell_settings
    {
        auto playSound = [this](const UTF8 &val) {
            currentSoundPath = val;
            this->audioModel.setVolume(this->provider->getCurrentVolume(), AbstractAudioModel::PlaybackType::PreWakeup);
            this->audioModel.play(this->soundsRepository->titleToPath(currentSoundPath).value_or(""),
                                  AbstractAudioModel::PlaybackType::PreWakeup,
                                  {});


@@ 30,7 31,8 @@ namespace app::bell_settings
        this->provider->onVolumeEnter  = playSound;
        this->provider->onVolumeExit   = [this](const auto &) { this->stopSound(); };
        this->provider->onVolumeChange = [this, playSound](const auto &val) {
            this->audioModel.setVolume(val, AbstractAudioModel::PlaybackType::PreWakeup, {});
            this->audioModel.setVolume(
                val, AbstractAudioModel::PlaybackType::PreWakeup, audio::VolumeUpdateType::SkipUpdateDB);
            if (this->audioModel.hasPlaybackFinished()) {
                playSound(currentSoundPath);
            }

M products/BellHybrid/apps/application-bell-settings/presenter/alarm_settings/SnoozePresenter.cpp => products/BellHybrid/apps/application-bell-settings/presenter/alarm_settings/SnoozePresenter.cpp +7 -3
@@ 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

#include "SnoozePresenter.hpp"


@@ 6,7 6,6 @@

namespace app::bell_settings
{

    SnoozePresenter::SnoozePresenter(std::shared_ptr<SnoozeListItemProvider> provider,
                                     std::unique_ptr<AbstractSnoozeSettingsModel> snoozeSettingsModel,
                                     AbstractAudioModel &audioModel,


@@ 16,6 15,7 @@ namespace app::bell_settings
    {
        auto playSound = [this](const UTF8 &val) {
            currentSoundPath = val;
            this->audioModel.setVolume(this->provider->getCurrentVolume(), AbstractAudioModel::PlaybackType::Snooze);
            this->audioModel.play(this->soundsRepository->titleToPath(currentSoundPath).value_or(""),
                                  AbstractAudioModel::PlaybackType::Snooze,
                                  {});


@@ 30,7 30,8 @@ namespace app::bell_settings
        this->provider->onVolumeEnter  = playSound;
        this->provider->onVolumeExit   = [this](const auto &) { stopSound(); };
        this->provider->onVolumeChange = [this, playSound](const auto &val) {
            this->audioModel.setVolume(val, AbstractAudioModel::PlaybackType::Snooze, {});
            this->audioModel.setVolume(
                val, AbstractAudioModel::PlaybackType::Snooze, audio::VolumeUpdateType::SkipUpdateDB);
            if (this->audioModel.hasPlaybackFinished()) {
                playSound(currentSoundPath);
            }


@@ 56,14 57,17 @@ namespace app::bell_settings
    {
        return provider;
    }

    void SnoozePresenter::stopSound()
    {
        audioModel.stopPlayedByThis({});
    }

    void SnoozePresenter::eraseProviderData()
    {
        provider->clearData();
    }

    void SnoozePresenter::exitWithoutSave()
    {
        snoozeSettingsModel->getSnoozeChimeVolume().restoreDefault();

M products/BellHybrid/apps/application-bell-settings/windows/BellSettingsLayoutWindow.cpp => products/BellHybrid/apps/application-bell-settings/windows/BellSettingsLayoutWindow.cpp +2 -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 "BellSettingsLayoutWindow.hpp"


@@ 8,7 8,7 @@

namespace
{
    inline constexpr auto arrowsOuterMargin = 48U;
    constexpr auto arrowsOuterMargin = 48U;
} // namespace

namespace gui


@@ 89,5 89,4 @@ namespace gui
        }
        return AppWindow::onInput(inputEvent);
    }

} // namespace gui

M products/BellHybrid/apps/common/include/common/models/AbstractAudioModel.hpp => products/BellHybrid/apps/common/include/common/models/AbstractAudioModel.hpp +4 -1
@@ 39,7 39,10 @@ namespace app
        using OnPlaybackFinishedCallback = std::function<void(PlaybackFinishStatus)>;

        virtual ~AbstractAudioModel() noexcept                                                              = default;
        virtual void setVolume(Volume volume, PlaybackType playbackType, OnStateChangeCallback &&callback)  = 0;
        virtual void setVolume(Volume volume,
                               PlaybackType playbackType,
                               audio::VolumeUpdateType updateType = audio::VolumeUpdateType::UpdateDB,
                               OnStateChangeCallback &&callback   = {})                                       = 0;
        virtual std::optional<Volume> getVolume(PlaybackType playbackType)                                  = 0;
        virtual void getVolume(PlaybackType playbackType, OnGetValueCallback &&callback)                    = 0;
        virtual void play(const std::string &filePath,

M products/BellHybrid/apps/common/include/common/models/AbstractSettingsModel.hpp => products/BellHybrid/apps/common/include/common/models/AbstractSettingsModel.hpp +1 -37
@@ 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

#pragma once


@@ 23,40 23,4 @@ namespace gui
        virtual void restoreDefault()
        {}
    };

    template <typename ValueT>
    class AsyncSettingsAdapter : public AbstractSettingsModel<ValueT>
    {
      public:
        std::function<void(ValueT)> onReady;

        void setValue(ValueT value) final
        {
            onSet(value);
        }

        ValueT getValue() const final
        {
            return currentValue;
        }

        void restoreDefault() final
        {
            onSet(defaultValue);
        }

      protected:
        std::function<void(ValueT)> onSet;

        void onUpdate(ValueT value)
        {
            currentValue = value;
            defaultValue = currentValue;
            onReady(currentValue);
        }

      private:
        ValueT currentValue{};
        ValueT defaultValue{};
    };
} // namespace gui

M products/BellHybrid/apps/common/include/common/models/AudioModel.hpp => products/BellHybrid/apps/common/include/common/models/AudioModel.hpp +4 -1
@@ 14,7 14,10 @@ namespace app
        explicit AudioModel(ApplicationCommon *app);
        virtual ~AudioModel();

        void setVolume(Volume volume, PlaybackType playbackType, OnStateChangeCallback &&callback) override;
        void setVolume(Volume volume,
                       PlaybackType playbackType,
                       audio::VolumeUpdateType updateType,
                       OnStateChangeCallback &&callback) override;
        std::optional<Volume> getVolume(PlaybackType playbackType) override;
        void getVolume(PlaybackType playbackType, OnGetValueCallback &&callback) override;
        void play(const std::string &filePath,

M products/BellHybrid/apps/common/include/common/widgets/list_items/details.hpp => products/BellHybrid/apps/common/include/common/widgets/list_items/details.hpp +13 -12
@@ 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


@@ 33,7 33,7 @@ namespace app::list_items
            void set_value(const value_type &value)
            {
                spinner->set_value(value);
                controlVisibility();
                control_visibility();
            }

            void set_range(const typename spinner_type::range &range)


@@ 53,7 53,8 @@ namespace app::list_items
            }

            /// Might be overridden if the specific handling of the bottom text is needed
            virtual void control_bottom_description(const value_type &value){};
            virtual void control_bottom_description(const value_type &value)
            {}

            explicit ListItemBase(typename SpinnerType::range &&range,
                                  gui::AbstractSettingsModel<value_type> &model,


@@ 74,7 75,7 @@ namespace app::list_items
                }

                spinner->onValueChanged = [this](const auto &val) {
                    controlVisibility();
                    control_visibility();
                    if (onValueChangeCb) {
                        onValueChangeCb(val);
                    }


@@ 83,21 84,21 @@ namespace app::list_items
                getValue = [this]() { this->model.setValue(this->spinner->value()); };
                setValue = [this]() {
                    this->spinner->set_value(this->model.getValue());
                    controlVisibility();
                    control_visibility();
                };

                inputCallback = [this, &bottomDescription](Item &, const gui::InputEvent &event) {
                inputCallback = [this]([[maybe_unused]] Item &item, const gui::InputEvent &event) {
                    return OnInputCallback(event);
                };

                focusChangedCallback = [this, &bottomDescription](Item &) {
                focusChangedCallback = [this]([[maybe_unused]] Item &item) {
                    OnFocusChangedCallback();
                    controlVisibility();
                    control_visibility();
                    return true;
                };
            }

            virtual void controlVisibility()
            virtual void control_visibility()
            {
                body->setMinMaxArrowsVisibility(spinner->is_min(), spinner->is_max());
                if (not this->bottomDescription.empty()) {


@@ 105,6 106,7 @@ namespace app::list_items
                    body->resize();
                }
            }

            SpinnerType *spinner{};
            gui::AbstractSettingsModel<value_type> &model;
            std::string bottomDescription;


@@ 147,14 149,13 @@ namespace app::list_items
            }

            gui::ArcProgressBar *progress = nullptr;
            void controlVisibility() override
            void control_visibility() override
            {
                ListItemBase<SpinnerType>::controlVisibility();
                ListItemBase<SpinnerType>::control_visibility();
                if (progress && this->spinner) {
                    progress->setValue(static_cast<unsigned int>(this->spinner->value()));
                }
            }
        };
    } // namespace details

} // namespace app::list_items

M products/BellHybrid/apps/common/src/AudioModel.cpp => products/BellHybrid/apps/common/src/AudioModel.cpp +3 -1
@@ 137,9 137,11 @@ namespace app

    void AudioModel::setVolume(AbstractAudioModel::Volume volume,
                               PlaybackType playbackType,
                               audio::VolumeUpdateType updateType,
                               OnStateChangeCallback &&callback)
    {
        auto msg = std::make_unique<service::AudioSetVolume>(convertPlaybackType(playbackType), std::to_string(volume));
        auto msg = std::make_unique<service::AudioSetVolume>(
            convertPlaybackType(playbackType), updateType, std::to_string(volume));
        auto task = app::AsyncRequest::createFromMessage(std::move(msg), service::audioServiceName);
        auto cb   = [_callback = callback](auto response) {
            auto result = dynamic_cast<service::AudioResponseMessage *>(response);

M products/BellHybrid/apps/common/src/layouts/ShortcutsLayoutClassic.cpp => products/BellHybrid/apps/common/src/layouts/ShortcutsLayoutClassic.cpp +9 -9
@@ 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 "layouts/ShortcutsLayoutClassic.hpp"


@@ 12,25 12,25 @@ namespace
{
    namespace container
    {
        constexpr inline auto width      = 544U;
        constexpr inline auto height     = 220U;
        constexpr inline auto top_margin = 74U;
        constexpr auto width      = 544U;
        constexpr auto height     = 220U;
        constexpr auto top_margin = 74U;

        namespace separator
        {
            constexpr inline auto height = 22U;
            constexpr auto height = 22U;
        } // namespace separator

        namespace image
        {
            constexpr inline auto height = container::height - separator::height;
            constexpr inline auto width  = 448U;
            constexpr auto height = container::height - separator::height;
            constexpr auto width  = 448U;
        } // namespace image

        namespace text
        {
            constexpr inline auto height = 146U;
            constexpr inline auto width  = 448U;
            constexpr auto height = 146U;
            constexpr auto width  = 448U;
        } // namespace text

    } // namespace container

M products/BellHybrid/apps/common/src/models/BedtimeModel.cpp => products/BellHybrid/apps/common/src/models/BedtimeModel.cpp +5 -9
@@ 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 "models/BedtimeModel.hpp"


@@ 17,12 17,7 @@ namespace app::bell_bedtime
    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;
        }
        return utils::toNumeric(str);
    }

    auto BedtimeTimeModel::writeString(std::string str) -> void


@@ 77,20 72,21 @@ namespace app::bell_bedtime

    void BedtimeVolumeModel::setValue(std::uint8_t value)
    {
        audioModel.setVolume(value, AbstractAudioModel::PlaybackType::Bedtime, {});
        audioModel.setVolume(value, AbstractAudioModel::PlaybackType::Bedtime);
    }

    auto BedtimeVolumeModel::getValue() const -> std::uint8_t
    {
        return defaultValue;
    }

    BedtimeVolumeModel::BedtimeVolumeModel(AbstractAudioModel &audioModel) : audioModel{audioModel}
    {
        defaultValue = audioModel.getVolume(AbstractAudioModel::PlaybackType::Bedtime).value_or(0);
    }

    void BedtimeVolumeModel::restoreDefault()
    {
        setValue(defaultValue);
    }

} // namespace app::bell_bedtime

M products/BellHybrid/apps/common/src/widgets/ProgressTimerWithSnoozeTimer.cpp => products/BellHybrid/apps/common/src/widgets/ProgressTimerWithSnoozeTimer.cpp +3 -4
@@ 1,18 1,17 @@
// 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

#include <common/widgets/ProgressTimerWithSnoozeTimer.hpp>
#include <common/widgets/SnoozeTimer.hpp>
#include <Text.hpp>
#include <ProgressBar.hpp>
#include <ApplicationCommon.hpp>
#include <apps-common/GuiTimer.hpp>
#include <gsl/assert>

namespace
{
    inline constexpr auto increasingModePrefix = "-";
    constexpr auto increasingModePrefix = "-";
}

namespace app
{
    void ProgressTimerWithSnoozeTimer::update()

M products/BellHybrid/services/audio/ServiceAudio.cpp => products/BellHybrid/services/audio/ServiceAudio.cpp +10 -8
@@ 117,7 117,7 @@ namespace service

        connect(typeid(AudioSetVolume), [this](sys::Message *msg) -> sys::MessagePointer {
            auto *msgl = static_cast<AudioSetVolume *>(msg);
            return handleSetVolume(msgl->playbackType, msgl->val);
            return handleSetVolume(msgl->playbackType, msgl->updateType, msgl->value);
        });

        connect(typeid(AudioGetVolume), [this](sys::Message *msg) -> sys::MessagePointer {


@@ 152,6 152,7 @@ namespace service

    sys::ReturnCodes Audio::DeinitHandler()
    {
        settingsProvider->deinit();
        LOG_INFO("Deinitialized");
        return sys::ReturnCodes::Success;
    }


@@ 315,20 316,21 @@ namespace service
        return ret;
    }

    auto Audio::handleSetVolume(const audio::PlaybackType &playbackType, const std::string &value)
        -> std::unique_ptr<AudioResponseMessage>
    auto Audio::handleSetVolume(const audio::PlaybackType &playbackType,
                                const audio::VolumeUpdateType &updateType,
                                const std::string &value) -> std::unique_ptr<AudioResponseMessage>
    {
        constexpr auto setting  = audio::Setting::Volume;
        auto retCode            = audio::RetCode::Success;
        const auto clampedValue = std::clamp(utils::getNumericValue<float>(value), minVolumeToSet, maxVolumeToSet);
        auto retCode            = audio::RetCode::Success;

        if (const auto activeInput = audioMux.GetActiveInput(); activeInput) {
            if (activeInput.value()) {
        if (const auto activeInput = audioMux.GetActiveInput(); activeInput.has_value()) {
            if (activeInput.value() != nullptr) {
                retCode = activeInput.value()->audio->SetOutputVolume(clampedValue);
            }
        }

        if (retCode == audio::RetCode::Success) {
        if ((updateType == audio::VolumeUpdateType::UpdateDB) && (retCode == audio::RetCode::Success)) {
            constexpr auto setting = audio::Setting::Volume;
            settingsProvider->setValue(dbPath(setting, playbackType, profileType), std::to_string(clampedValue));
        }
        return std::make_unique<AudioResponseMessage>(retCode);

M products/BellHybrid/services/audio/include/audio/AudioMessage.hpp => products/BellHybrid/services/audio/include/audio/AudioMessage.hpp +9 -5
@@ 65,12 65,12 @@ namespace service
    class AudioSettingsMessage : public AudioMessage
    {
      public:
        AudioSettingsMessage(const audio::PlaybackType &playbackType, const std::string &val = {})
            : AudioMessage{}, playbackType{playbackType}, val{val}
        AudioSettingsMessage(const audio::PlaybackType &playbackType, const std::string &value = {})
            : AudioMessage{}, playbackType{playbackType}, value{value}
        {}

        audio::PlaybackType playbackType = audio::PlaybackType::None;
        std::string val{};
        std::string value{};
    };

    class AudioGetVolume : public AudioSettingsMessage


@@ 83,9 83,13 @@ namespace service
    class AudioSetVolume : public AudioSettingsMessage
    {
      public:
        AudioSetVolume(const audio::PlaybackType &playbackType, const std::string &val)
            : AudioSettingsMessage{playbackType, val}
        AudioSetVolume(const audio::PlaybackType &playbackType,
                       const audio::VolumeUpdateType updateType,
                       const std::string &val)
            : AudioSettingsMessage{playbackType, val}, updateType{updateType}
        {}

        audio::VolumeUpdateType updateType;
    };

    class AudioStopRequest : public AudioMessage

M products/BellHybrid/services/audio/include/audio/ServiceAudio.hpp => products/BellHybrid/services/audio/include/audio/ServiceAudio.hpp +3 -3
@@ 49,8 49,9 @@ namespace service
        auto handleStop(const std::vector<audio::PlaybackType> &stopTypes, const audio::Token &token)
            -> std::unique_ptr<AudioResponseMessage>;

        auto handleSetVolume(const audio::PlaybackType &playbackType, const std::string &value)
            -> std::unique_ptr<AudioResponseMessage>;
        auto handleSetVolume(const audio::PlaybackType &playbackType,
                             const audio::VolumeUpdateType &updateType,
                             const std::string &value) -> std::unique_ptr<AudioResponseMessage>;
        auto handleGetVolume(const audio::PlaybackType &playbackType) -> std::unique_ptr<AudioResponseMessage>;
        auto getVolume(const audio::PlaybackType &playbackType) -> audio::Volume;



@@ 76,7 77,6 @@ namespace service
        std::unique_ptr<settings::Settings> settingsProvider;
        std::unique_ptr<audio::VolumeFadeIn> volumeFadeIn;
    };

} // namespace service

namespace sys