~aleteoryx/muditaos

515026f3bac6b8b3a80fbd7715cb0cd49882ffd7 — Przemyslaw Brudny 4 years ago 6784e6b + d111ce0
Merge remote-tracking branch 'origin/stable'
48 files changed, 212 insertions(+), 390 deletions(-)

M Jenkinsfile
M docker/Dockerfile.runner.in
M image/assets/lang/Deutsch.json
M image/assets/lang/English.json
M image/assets/lang/Espanol.json
M image/assets/lang/Francais.json
M image/assets/lang/Polski.json
M image/user/db/settings_bell_002.sql
M module-services/service-evtmgr/EventManager.cpp
M module-services/service-time/AlarmOperations.cpp
M module-services/service-time/AlarmOperations.hpp
M products/BellHybrid/apps/Application.cpp
M products/BellHybrid/apps/application-bell-alarm/data/BellAlarmStyle.hpp
M products/BellHybrid/apps/application-bell-alarm/windows/BellAlarmSetWindow.cpp
M products/BellHybrid/apps/application-bell-background-sounds/ApplicationBellBackgroundSounds.cpp
M products/BellHybrid/apps/application-bell-background-sounds/include/application-bell-background-sounds/ApplicationBellBackgroundSounds.hpp
M products/BellHybrid/apps/application-bell-background-sounds/widgets/BGSoundsPlayer.cpp
M products/BellHybrid/apps/application-bell-main/presenters/StateController.cpp
M products/BellHybrid/apps/application-bell-meditation-timer/ApplicationBellMeditationTimer.cpp
M products/BellHybrid/apps/application-bell-meditation-timer/include/application-bell-meditation-timer/ApplicationBellMeditationTimer.hpp
M products/BellHybrid/apps/application-bell-meditation-timer/presenter/IntervalChimePresenter.cpp
M products/BellHybrid/apps/application-bell-meditation-timer/presenter/MeditationProgressPresenter.cpp
M products/BellHybrid/apps/application-bell-meditation-timer/windows/MeditationRunningWindow.cpp
M products/BellHybrid/apps/application-bell-onboarding/windows/OnBoardingFinalizeWindow.cpp
M products/BellHybrid/apps/application-bell-powernap/ApplicationBellPowerNap.cpp
M products/BellHybrid/apps/application-bell-powernap/include/application-bell-powernap/ApplicationBellPowerNap.hpp
M products/BellHybrid/apps/application-bell-powernap/presenter/PowerNapMainWindowPresenter.cpp
M products/BellHybrid/apps/application-bell-powernap/presenter/PowerNapProgressPresenter.cpp
M products/BellHybrid/apps/application-bell-powernap/windows/PowerNapProgressWindow.cpp
M products/BellHybrid/apps/application-bell-settings/ApplicationBellSettings.cpp
M products/BellHybrid/apps/application-bell-settings/include/application-bell-settings/ApplicationBellSettings.hpp
M products/BellHybrid/apps/application-bell-settings/include/application-bell-settings/models/TimeUnitsModel.hpp
M products/BellHybrid/apps/application-bell-settings/models/alarm_settings/SnoozeListItemProvider.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/common/include/common/models/AbstractAudioModel.hpp
M products/BellHybrid/apps/common/include/common/models/AudioModel.hpp
M products/BellHybrid/apps/common/src/AudioModel.cpp
M products/BellHybrid/apps/include/Application.hpp
M products/BellHybrid/services/audio/ServiceAudio.cpp
M products/BellHybrid/services/evtmgr/EventManager.cpp
M products/BellHybrid/services/time/AlarmOperations.cpp
M products/BellHybrid/services/time/include/time/AlarmOperations.hpp
M products/PurePhone/services/evtmgr/EventManager.cpp
M products/PurePhone/services/time/AlarmOperations.cpp
M products/PurePhone/services/time/include/time/AlarmOperations.hpp
M Jenkinsfile => Jenkinsfile +32 -277
@@ 1,20 1,5 @@
def cancelPreviousBuilds() {
@Library('PureCI') _

    def jobName = env.JOB_NAME
    def buildNumber = env.BUILD_NUMBER.toInteger()
    def currentJob = Jenkins.instance.getItemByFullName(jobName)

    for (def build : currentJob.builds) {
        def exec = build.getExecutor()

        /* Kill older jobs */
        if (build.isBuilding() && build.number.toInteger() < buildNumber && exec != null) {
            def cause = { "Job stoped by #${buildNumber}" as String} as CauseOfInterruption
            exec.interrupt(Result.ABORTED, cause)
            println("Aborting previous build:#${build.number}")
        }
    }
}
pipeline {
    agent {
        node {


@@ 29,13 14,15 @@ pipeline {
    environment {
        JOBS=30
        PATH="/usr/local/cmake-3.21.3-linux-x86_64/bin:/usr/local/gcc-arm-none-eabi-10-2020-q4-major/bin:$PATH"
        REPO_WORKSPACE="/home/jenkins/workspace/MuditaOS"

    }

    stages {
        stage('Check for previous running builds') {
            steps {
                script {
                    cancelPreviousBuilds()
                    common.cancelPreviousBuilds()
                }
            }
        }


@@ 49,282 36,56 @@ pipeline {
                GITHUB_HEAD_REF="${pullRequest.headRef}"
            }
            steps {
                withCredentials([string(credentialsId: 'f412733a-851c-4f87-ad24-7da2139a98ca', variable: 'TOKEN')]) {
                    sh ''' #!/bin/bash -e
                    git config --add --global user.apitoken ${TOKEN}
                    '''
                }
                echo "install additional python dependencies"
                sh '''#!/bin/bash -e
                python3 -m pip install ghapi
                '''
                echo "Check if branch needs rebasing"
                sh '''#!/bin/bash -e
                pushd ${WORKSPACE}
                if [ $(git rev-list --count origin/${CHANGE_TARGET}...`(git merge-base ${GIT_COMMIT}  origin/${CHANGE_TARGET})`) = 0 ]; then
                    echo "Branch OK"
                else
                    echo "Branch is not rebased. Exiting"
                    exit 1
                fi
                popd'''

                echo "Commit Message check"
                sh '''#!/bin/bash -e
                pushd ${WORKSPACE}
                ./tools/check_commit_messages.py
                popd'''

                echo "Copyright notice check"
                sh '''#!/bin/bash -e
                pushd ${WORKSPACE}
                ./config/license_header_check.sh --ci --check-only
                popd'''

                echo "Style checking"
                sh '''#!/bin/bash -e
                pushd ${WORKSPACE}
                ./config/style_check_hook.sh --last
                popd'''
                script{
                    buildSteps.performChecks("false");
                }
            }
        stage('Build RT1051') {
            environment {
                CCACHE_DIR="/ccache/"
                XDG_CACHE_HOME="/clang-cache"
            }
        }
        stage('Build RT1051 - PurePhone') {
            steps {
                echo "Check if branch needs rebasing"
                sh '''#!/bin/bash -e
                pushd ${WORKSPACE}
                if [ $(git rev-list --count origin/${CHANGE_TARGET}...`(git merge-base ${GIT_COMMIT}  origin/${CHANGE_TARGET})`) = 0 ]; then
                    echo "Branch OK"
                else
                    echo "Branch is not rebased. Exiting"
                    exit 1
                fi
                popd'''

                sh '''#!/bin/bash -e
                export JOBS=${JOBS}
                export CCACHE_DIR=/ccache/
                echo "JOBS=${JOBS}"

                echo "cmake path=$(which cmake)"
                echo "\'workspace dir:${WORKSPACE}\'"

                pushd "${WORKSPACE}"

                echo "./configure.sh pure rt1051 Release -G Ninja"
                ./configure.sh pure rt1051 Release -G Ninja

                pushd build-PurePhone-rt1051-Release
                ninja -j ${JOBS} PurePhone-boot.bin
                popd
                rm -r build-PurePhone-rt1051-Release

                echo "./configure.sh bell rt1051 Release -G Ninja"
                ./configure.sh bell rt1051 Release -G Ninja

                pushd build-BellHybrid-rt1051-Release
                ninja -j ${JOBS} BellHybrid-boot.bin
                popd

                echo "disk usage before removal:"
                du -h --max-depth=1 .

                rm -r build-BellHybrid-rt1051-Release

                echo "disk usage after removal:"
                du -h --max-depth=1 .

                popd'''
                echo "CCache stats"
                sh '''#!/bin/bash
                export CCACHE_DIR=/ccache/
                ccache --show-stats'''
                script{
                    common.checkIfBranchIsRebased("false")
                    buildSteps.build("rt1051","PurePhone","Release")
                }
            }
        }

        stage('Build Linux - Pure') {
            environment {
                CCACHE_DIR="/ccache/"
                XDG_CACHE_HOME="/clang-cache"

        stage('Build RT1051 - BellHybrid') {
            steps {
                script{
                    common.checkIfBranchIsRebased("false")
                    buildSteps.build("rt1051","BellHybrid","Release")
                }
            }
        }

        stage('Build Linux - PurePhone') {
            when {
                expression {
                 return !(env.CHANGE_TARGET ==~ /release\/[0-9]+\.[0-9]+\.[0-9]+-bell/)
                 }
            }
            steps {
                echo "Check if branch needs rebasing"
                sh '''#!/bin/bash -e
                pushd ${WORKSPACE}
                if [ $(git rev-list --count origin/${CHANGE_TARGET}...`(git merge-base ${GIT_COMMIT}  origin/${CHANGE_TARGET})`) = 0 ]; then
                    echo "Branch OK"
                else
                    echo "Branch is not rebased. Exiting"
                    exit 1
                fi
                popd'''

                echo "Configure"
                sh '''#!/bin/bash -e
                echo "JOBS=${JOBS}"
                pushd "${WORKSPACE}"

                echo "./configure.sh pure linux Debug -G Ninja"
                ./configure.sh pure linux Debug -G Ninja
                popd'''

                echo "Clang Tidy check"
                /* requires compilation database - must be run after configuration */
                sh '''#!/bin/bash -e
                pushd ${WORKSPACE}
                ./config/clang_check.sh PurePhone
                popd'''

                echo "Build"
                sh '''#!/bin/bash -e
                echo "JOBS=${JOBS}"
                pushd "${WORKSPACE}"

                pushd build-PurePhone-linux-Debug
                ninja -j ${JOBS} PurePhone-boot.bin
                popd
                popd'''

                echo "Build Unit Tests"
                sh '''#!/bin/bash -e
                pushd "${WORKSPACE}"
                pushd build-PurePhone-linux-Debug
                ninja -j ${JOBS} unittests
                popd'''

                echo "CCache stats"
                sh '''#!/bin/bash
                export CCACHE_DIR=/ccache/
                ccache --show-stats'''

                echo "Check for Statics"
                sh '''#!/bin/bash -e
                pushd "${WORKSPACE}"
                ./tools/find_global_data.py build-PurePhone-linux-Debug/PurePhone.elf
                popd'''

                echo "Run Unit Tests"
                sh '''#!/bin/bash -e
                export JOBS=${JOBS}
                echo "JOBS=${JOBS}"

                pushd "${WORKSPACE}"
                pushd build-PurePhone-linux-Debug
                ninja check -j ${JOBS}
                popd

                echo "disk usage before removal:"
                du -h --max-depth=1 .

                rm -r build-PurePhone-linux-Debug

                echo "disk usage after removal:"
                du -h --max-depth=1 .
                popd'''
                script{
                    common.checkIfBranchIsRebased("false")
                    buildSteps.build("linux","PurePhone","Debug")
                }
            }
        }


        stage('Build Linux - Bell') {
            environment {
                CCACHE_DIR="/ccache/"
                XDG_CACHE_HOME="/clang-cache"
            }
        stage('Build Linux - BellHybrid') {
            when {
                expression {
                 return !(env.CHANGE_TARGET ==~ /release\/[0-9]+\.[0-9]+\.[0-9]+-pure/)
                 }
            }
            steps {
                echo "Check if branch needs rebasing"
                sh '''#!/bin/bash -e
                pushd ${WORKSPACE}
                if [ $(git rev-list --count origin/${CHANGE_TARGET}...`(git merge-base ${GIT_COMMIT}  origin/${CHANGE_TARGET})`) = 0 ]; then
                    echo "Branch OK"
                else
                    echo "Branch is not rebased. Exiting"
                    exit 1
                fi
                popd'''

                echo "Configure"
                sh '''#!/bin/bash -e
                echo "JOBS=${JOBS}"
                pushd "${WORKSPACE}"
                echo "./configure.sh bell linux Debug -G Ninja"

                ./configure.sh bell linux Debug -G Ninja

                popd'''
                echo "Clang Tidy check"
                /* requires compilation database - must be run after configuration */
                sh '''#!/bin/bash -e
                pushd ${WORKSPACE}
                ./config/clang_check.sh BellHybrid
                popd'''

                echo "Build"
                sh '''#!/bin/bash -e
                echo "JOBS=${JOBS}"
                pushd "${WORKSPACE}"

                pushd build-BellHybrid-linux-Debug
                ninja -j ${JOBS} BellHybrid-boot.bin
                popd

                popd'''

                echo "Build Unit Tests"
                sh '''#!/bin/bash -e
                pushd "${WORKSPACE}"

                pushd "${WORKSPACE}"
                pushd build-BellHybrid-linux-Debug
                ninja -j ${JOBS} unittests
                popd
                popd'''

                echo "CCache stats"
                sh '''#!/bin/bash
                export CCACHE_DIR=/ccache/
                ccache --show-stats'''

                echo "Check for Statics"
                sh '''#!/bin/bash -e
                pushd "${WORKSPACE}"
                ./tools/find_global_data.py build-BellHybrid-linux-Debug/BellHybrid.elf
                popd'''

                echo "Run Unit Tests"
                sh '''#!/bin/bash -e
                export JOBS=${JOBS}
                echo "JOBS=${JOBS}"
                pushd "${WORKSPACE}"

                pushd build-BellHybrid-linux-Debug
                ninja check -j ${JOBS}
                popd

                echo "disk usage before removal:"
                du -h --max-depth=1 .

                rm -r build-BellHybrid-linux-Debug

                echo "disk usage after removal:"
                du -h --max-depth=1 .
                popd'''
                script{
                    common.checkIfBranchIsRebased("false")
                    buildSteps.build("linux","BellHybrid","Debug")
                }
            }
        }

        stage('master-jobs') {
            when {


@@ 337,18 98,12 @@ pipeline {
                '''
            }
        }

    }
    post {
        cleanup {
            deleteDir()
            dir("${workspace}@tmp") {
                deleteDir()
            }
            dir("${workspace}@script") {
                deleteDir()
            script{
                common.cleanup("false")
            }
        }
    }

}

M docker/Dockerfile.runner.in => docker/Dockerfile.runner.in +7 -1
@@ 5,7 5,8 @@ MAINTAINER ops@mudita.com

RUN ln -fs /usr/share/zoneinfo/@DOCKER_TIMEZONE@ /etc/localtime
RUN export DEBIAN_FRONTEND=noninteractive 
RUN apt-get update 
RUN apt-get update

RUN apt-get full-upgrade -y 
RUN apt-get install -y \
        @INSTALL_PACKAGES@


@@ 21,6 22,11 @@ RUN mkdir -p /home/runner/app/settings

RUN update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-10 1000 --slave /usr/bin/g++ g++ /usr/bin/g++-10

RUN apt-get install software-properties-common -y
RUN add-apt-repository ppa:git-core/ppa -y
RUN apt-get update
RUN apt-get install git -y

#add python packages
ADD assets/requirements.txt /home/docker/requirements.txt
RUN pip3 install -r /home/docker/requirements.txt

M image/assets/lang/Deutsch.json => image/assets/lang/Deutsch.json +0 -1
@@ 605,7 605,6 @@
  "app_bell_settings_time_units_time_fmt_top_message": "Zeitformat",
  "app_bell_settings_time_units_time_message": "Zeit",
  "app_bell_settings_advanced_temp_scale": "Temperaturskala",
  "app_bell_onboarding_finalize": "Gut gemacht!",
  "app_bell_onboarding_welcome": "Willkommen",
  "app_bellmain_home_screen_bottom_desc_dp": "Tief drücken, um zu aktivieren",
  "app_bellmain_home_screen_bottom_desc": "Der nächste Alarm klingelt",

M image/assets/lang/English.json => image/assets/lang/English.json +0 -1
@@ 603,7 603,6 @@
  "app_bell_onboarding_info_light_click": "<text font='gt_pressura' weight='regular' size='38'>Light click </text><text font='gt_pressura' weight='light' size='38'>to continue</text>",
  "app_bell_onboarding_info_deep_click_warning": "<text font='gt_pressura' weight='light' size='38'>You've </text><text font='gt_pressura' weight='regular' size='38'>deep pressed</text>",
  "app_bell_onboarding_info_deep_click_correction": "<text font='gt_pressura' weight='light' size='38'>Be more gentle,<br></br>try </text><text font='gt_pressura' weight='regular' size='38'>light click </text><text font='gt_pressura' weight='light' size='38'>this time</text>",
  "app_bell_onboarding_finalize": "Well done!",
  "app_bell_onboarding_welcome": "Welcome",
  "app_bell_settings_advanced": "Advanced",
  "app_bell_settings_time_units": "Time & units",

M image/assets/lang/Espanol.json => image/assets/lang/Espanol.json +0 -1
@@ 610,7 610,6 @@
  "app_bell_settings_time_units_time_fmt_top_message": "Formato de hora",
  "app_bell_settings_time_units_time_message": "Hora",
  "app_bell_settings_advanced_temp_scale": "Escala de temperatura",
  "app_bell_onboarding_finalize": "¡Bien hecho!",
  "app_bell_onboarding_welcome_message": "Mudita Harmony",
  "app_bell_onboarding_info_rotate": "<text font='gt_pressura' weight='regular' size='38'>Girar </text><text font='gt_pressura' weight='light' size='38'> para seleccionar</text>",
  "app_bell_onboarding_info_light_click": "<text font='gt_pressura' weight='regular' size='38'>Click ligeramente </text><text font='gt_pressura' weight='light' size='38'>para continuar</text>",

M image/assets/lang/Francais.json => image/assets/lang/Francais.json +0 -1
@@ 584,7 584,6 @@
  "app_bell_settings_time_units_time_fmt_top_message": "Format de l'heure",
  "app_bell_settings_time_units_time_message": "Heure",
  "app_bell_settings_advanced_temp_scale": "Échelle de température",
  "app_bell_onboarding_finalize": "Bien!",
  "app_bell_onboarding_welcome_message": "Mudita Harmony",
  "app_bell_onboarding_info_rotate": "<text font='gt_pressura' weight='regular' size='38'>Tourner </text><text font='gt_pressura' weight='light' size='38'>pour sélectionner</text>",
  "app_bell_onboarding_info_light_click": "<text font='gt_pressura' weight='regular' size='38'>Cliquer doucement </text><text font='gt_pressura' weight='light' size='38'>pour continuer</text>",

M image/assets/lang/Polski.json => image/assets/lang/Polski.json +0 -1
@@ 619,7 619,6 @@
  "app_bellmain_background_sounds": "Relaks",
  "app_bellmain_settings": "Ustawienia",
  "app_bellmain_main_window_title": "Mudita Harmony",
  "app_bell_onboarding_finalize": "Dobra robota!",
  "app_bell_onboarding_welcome_message": "Mudita Harmony",
  "app_bell_onboarding_info_rotate": "<text font='gt_pressura' weight='regular' size='38'>Obróć, </text><text font='gt_pressura' weight='light' size='38'>aby wybrać</text>",
  "app_bell_onboarding_info_light_click": "<text font='gt_pressura' weight='regular' size='38'>Kliknij lekko, </text><text font='gt_pressura' weight='light' size='38'>aby kontynuować</text>",

M image/user/db/settings_bell_002.sql => image/user/db/settings_bell_002.sql +4 -4
@@ 33,12 33,12 @@ INSERT OR IGNORE INTO settings_tab (path, value) VALUES
    ('temperature_unit', 'C'),
    ('snooze_active', '1'),
    ('snooze_length','10'),
    ('snooze_interval','1'),
    ('snooze_interval','0'),
    ('snooze_tone','Gentle Chime'),
    ('prewake_up_duration', '10'),
    ('prewake_up_duration', '0'),
    ('prewake_up_tone','Joyful Awakening'),
    ('prewake_up_light_duration','10'),
    ('alarm_tone','Gentle Daybreak'),
    ('prewake_up_light_duration','0'),
    ('alarm_tone','Brand New Morning'),
    ('alarm_light_active','1'),
    ('alarm_duration','10000'),
    ('bedtime_active','0'),

M module-services/service-evtmgr/EventManager.cpp => module-services/service-evtmgr/EventManager.cpp +0 -7
@@ 284,13 284,6 @@ void EventManagerCommon::handleKeyEvent(sys::Message *msg)
    auto message    = std::make_shared<sevm::KbdMessage>();
    message->key    = kbdMessage->key;

    if (message->key.state == RawKey::State::Pressed) {
        const auto code = message->key.keyCode;
        if (code == bsp::KeyCodes::FnRight) {
            bus.sendUnicast(message, service::name::system_manager);
        }
    }

    // send key to focused application
    if (!targetApplication.empty()) {
        bus.sendUnicast(message, targetApplication);

M module-services/service-time/AlarmOperations.cpp => module-services/service-time/AlarmOperations.cpp +3 -5
@@ 269,12 269,12 @@ namespace alarms
        }
    }

    auto AlarmOperationsCommon::minuteUpdated(TimePoint now) -> bool
    auto AlarmOperationsCommon::minuteUpdated(TimePoint now) -> void
    {
        return processEvents(now);
        processEvents(now);
    }

    bool AlarmOperationsCommon::processEvents(TimePoint now)
    void AlarmOperationsCommon::processEvents(TimePoint now)
    {
        const auto isHandlingInProgress = !ongoingSingleEvents.empty();
        if (!nextSingleEvents.empty()) {


@@ 287,9 287,7 @@ namespace alarms

        if (!isHandlingInProgress) {
            processOngoingEvents();
            return true;
        }
        return false;
    }

    void AlarmOperationsCommon::processOngoingEvents()

M module-services/service-time/AlarmOperations.hpp => module-services/service-time/AlarmOperations.hpp +19 -19
@@ 39,31 39,31 @@ namespace alarms

        virtual void updateEventsCache(TimePoint now) = 0;

        virtual void getAlarm(const std::uint32_t alarmId, OnGetAlarmProcessed callback)              = 0;
        virtual void getAlarm(const std::uint32_t alarmId, OnGetAlarmProcessed callback)                     = 0;
        virtual void getAlarmWithStatus(const std::uint32_t alarmId, OnGetAlarmWithStatusProcessed callback) = 0;
        virtual void addAlarm(AlarmEventRecord record, OnAddAlarmProcessed callback)                  = 0;
        virtual void updateAlarm(AlarmEventRecord record, OnUpdateAlarmProcessed callback)            = 0;
        virtual void removeAlarm(const std::uint32_t alarmId, OnRemoveAlarmProcessed callback)        = 0;
        virtual void addAlarm(AlarmEventRecord record, OnAddAlarmProcessed callback)                         = 0;
        virtual void updateAlarm(AlarmEventRecord record, OnUpdateAlarmProcessed callback)                   = 0;
        virtual void removeAlarm(const std::uint32_t alarmId, OnRemoveAlarmProcessed callback)               = 0;
        virtual void getAlarmsInRange(std::uint32_t offset,
                                      std::uint32_t limit,
                                      OnGetAlarmsInRangeProcessed callback)                           = 0;
        virtual void getNextSingleEvents(TimePoint start, OnGetAlarmsProcessed callback)              = 0;
        virtual void turnOffRingingAlarm(const std::uint32_t id, OnTurnOffRingingAlarm callback)      = 0;
        virtual void turnOffSnoozedAlarm(const std::uint32_t id, OnTurnOffRingingAlarm callback)      = 0;
                                      OnGetAlarmsInRangeProcessed callback)                                  = 0;
        virtual void getNextSingleEvents(TimePoint start, OnGetAlarmsProcessed callback)                     = 0;
        virtual void turnOffRingingAlarm(const std::uint32_t id, OnTurnOffRingingAlarm callback)             = 0;
        virtual void turnOffSnoozedAlarm(const std::uint32_t id, OnTurnOffRingingAlarm callback)             = 0;
        virtual void snoozeRingingAlarm(const std::uint32_t id,
                                        const TimePoint nextAlarmTime,
                                        OnSnoozeRingingAlarm callback)                                = 0;
                                        OnSnoozeRingingAlarm callback)                                       = 0;
        virtual void postponeSnooze(const std::uint32_t id,
                                    const TimePoint nextAlarmTime,
                                    OnSnoozeRingingAlarm callback)                                    = 0;
        virtual bool minuteUpdated(TimePoint now)                                                            = 0;
                                    OnSnoozeRingingAlarm callback)                                           = 0;
        virtual void minuteUpdated(TimePoint now)                                                            = 0;
        virtual void addAlarmExecutionHandler(const alarms::AlarmType type,
                                              const std::shared_ptr<alarms::AlarmHandler> handler)    = 0;
        virtual void stopAllSnoozedAlarms()                                                           = 0;
        virtual void addSnoozedAlarmsCountChangeCallback(OnSnoozedAlarmsCountChange)                  = 0;
        virtual void addActiveAlarmCountChangeCallback(OnActiveAlarmCountChange)                      = 0;
        virtual void toggleAll(bool toggle, OnToggleAll callback)                                     = 0;
        virtual void getSnoozedAlarms(OnGetSnoozedAlarms callback)                                    = 0;
                                              const std::shared_ptr<alarms::AlarmHandler> handler)           = 0;
        virtual void stopAllSnoozedAlarms()                                                                  = 0;
        virtual void addSnoozedAlarmsCountChangeCallback(OnSnoozedAlarmsCountChange)                         = 0;
        virtual void addActiveAlarmCountChangeCallback(OnActiveAlarmCountChange)                             = 0;
        virtual void toggleAll(bool toggle, OnToggleAll callback)                                            = 0;
        virtual void getSnoozedAlarms(OnGetSnoozedAlarms callback)                                           = 0;
    };

    class IAlarmOperationsFactory


@@ 100,7 100,7 @@ namespace alarms
        void postponeSnooze(const std::uint32_t id,
                            const TimePoint nextAlarmTime,
                            OnSnoozeRingingAlarm callback) override;
        bool minuteUpdated(TimePoint now) override;
        void minuteUpdated(TimePoint now) override;
        void addAlarmExecutionHandler(const alarms::AlarmType type,
                                      const std::shared_ptr<alarms::AlarmHandler> handler) override;
        void stopAllSnoozedAlarms() override;


@@ 140,7 140,7 @@ namespace alarms
                                     OnGetAlarmsProcessed handledCallback);
        void checkAndUpdateCache(AlarmEventRecord record);
        void switchAlarmExecution(const SingleEventRecord &singleAlarmEvent, bool newStateOn);
        bool processEvents(TimePoint now);
        void processEvents(TimePoint now);
        void processOngoingEvents();
        void processNextEventsQueue(const TimePoint now);
        void processSnoozedEventsQueue(const TimePoint now);

M products/BellHybrid/apps/Application.cpp => products/BellHybrid/apps/Application.cpp +14 -2
@@ 117,7 117,6 @@ namespace app
    void Application::onStop()
    {
        stopIdleTimer();
        stopAllAudio();
    }

    void Application::stopAllAudio()


@@ 133,7 132,9 @@ namespace app

    void Application::restartIdleTimer()
    {
        bus.sendUnicast(std::make_shared<RestartIdleTimerMessage>(), service::name::appmgr);
        if (idleTimerActiveFlag) {
            bus.sendUnicast(std::make_shared<RestartIdleTimerMessage>(), service::name::appmgr);
        }
    }

    void Application::stopIdleTimer()


@@ 143,4 144,15 @@ namespace app

    void Application::updateStatuses(gui::AppWindow *window) const
    {}

    void Application::resumeIdleTimer()
    {
        startIdleTimer();
        idleTimerActiveFlag = true;
    }
    void Application::suspendIdleTimer()
    {
        stopIdleTimer();
        idleTimerActiveFlag = false;
    }
} // namespace app

M products/BellHybrid/apps/application-bell-alarm/data/BellAlarmStyle.hpp => products/BellHybrid/apps/application-bell-alarm/data/BellAlarmStyle.hpp +6 -0
@@ 19,5 19,11 @@ namespace gui
        {
            inline constexpr auto font = style::window::font::largelight;
        }

        namespace icon
        {
            constexpr inline auto imageTopMargin    = 112;
            constexpr inline auto imageBottomMargin = 30;
        } // namespace icon
    } // namespace bell_alarm_style
} // namespace gui

M products/BellHybrid/apps/application-bell-alarm/windows/BellAlarmSetWindow.cpp => products/BellHybrid/apps/application-bell-alarm/windows/BellAlarmSetWindow.cpp +3 -0
@@ 34,6 34,9 @@ namespace gui
        navBar->setVisible(false);

        icon = new Icon(this, 0, 0, style::window_width, style::window_height, {}, {});
        icon->setAlignment(Alignment(Alignment::Horizontal::Center, Alignment::Vertical::Top));
        icon->image->setMargins(
            {0, bell_alarm_style::icon::imageTopMargin, 0, bell_alarm_style::icon::imageBottomMargin});
        icon->text->setFont(style::window::font::verybiglight);
    }


M products/BellHybrid/apps/application-bell-background-sounds/ApplicationBellBackgroundSounds.cpp => products/BellHybrid/apps/application-bell-background-sounds/ApplicationBellBackgroundSounds.cpp +6 -0
@@ 108,4 108,10 @@ namespace app
        }
        return ApplicationCommon::handleSwitchWindow(msgl);
    }

    void ApplicationBellBackgroundSounds::onStop()
    {
        Application::onStop();
        audioModel->stopPlayedByThis({});
    }
} // namespace app

M products/BellHybrid/apps/application-bell-background-sounds/include/application-bell-background-sounds/ApplicationBellBackgroundSounds.hpp => products/BellHybrid/apps/application-bell-background-sounds/include/application-bell-background-sounds/ApplicationBellBackgroundSounds.hpp +1 -0
@@ 26,6 26,7 @@ namespace app
        std::unique_ptr<AbstractAudioModel> audioModel;
        std::unique_ptr<bgSounds::BGSoundsPlayer> player;

        void onStop() override;
        sys::MessagePointer handleSwitchWindow(sys::Message *msgl) override;

      public:

M products/BellHybrid/apps/application-bell-background-sounds/widgets/BGSoundsPlayer.cpp => products/BellHybrid/apps/application-bell-background-sounds/widgets/BGSoundsPlayer.cpp +1 -1
@@ 28,7 28,7 @@ namespace app::bgSounds
    void BGSoundsPlayer::stop(AbstractAudioModel::OnStateChangeCallback &&callback)
    {
        paused = false;
        audioModel.stop(std::move(callback));
        audioModel.stopPlayedByThis(std::move(callback));
    }
    void BGSoundsPlayer::pause(AbstractAudioModel::OnStateChangeCallback &&callback)
    {

M products/BellHybrid/apps/application-bell-main/presenters/StateController.cpp => products/BellHybrid/apps/application-bell-main/presenters/StateController.cpp +8 -7
@@ 161,10 161,12 @@ namespace app::home_screen

        namespace AlarmEdit
        {
            auto entry = [](AbstractView &view, AbstractPresenter &presenter) {
                view.setAlarmEdit(true);
                view.setHeaderViewMode(HeaderViewMode::AlarmIconAndTime);
            };
            auto entry =
                [](AbstractView &view, AbstractPresenter &presenter, AbstractTemperatureModel &temperatureModel) {
                    view.setAlarmEdit(true);
                    view.setHeaderViewMode(HeaderViewMode::AlarmIconAndTime);
                    view.setTemperature(temperatureModel.getTemperature());
                };
            auto exit = [](AbstractView &view, AbstractPresenter &presenter) {
                view.setAlarmEdit(false);
                presenter.detachTimer();


@@ 256,8 258,6 @@ namespace app::home_screen
                presenter.spawnTimer();
                alarmModel.snooze();
                view.setHeaderViewMode(HeaderViewMode::SnoozeCountdown);

                const auto snoozeDuration = alarmModel.getTimeToNextSnooze();
                view.setSnoozeTime(alarmModel.getTimeOfNextSnooze());
                const auto bottomDescription = utils::translate("app_bellmain_home_screen_bottom_desc") + " " +
                                               std::to_string(alarmModel.getSnoozeDuration()) + " min";


@@ 269,9 269,10 @@ namespace app::home_screen
        namespace AlarmSnoozed
        {
            auto entry =
                [](AbstractView &view, AbstractPresenter &presenter, AbstractTemperatureModel &temperatureModel) {
                [](AbstractView &view, AbstractAlarmModel &alarmModel, AbstractTemperatureModel &temperatureModel) {
                    view.setHeaderViewMode(HeaderViewMode::SnoozeCountdown);
                    view.setTemperature(temperatureModel.getTemperature());
                    view.setSnoozeTime(alarmModel.getTimeOfNextSnooze());
                };
            auto exit = [](AbstractPresenter &presenter) { presenter.stopSnoozeTimer(); };
        } // namespace AlarmSnoozed

M products/BellHybrid/apps/application-bell-meditation-timer/ApplicationBellMeditationTimer.cpp => products/BellHybrid/apps/application-bell-meditation-timer/ApplicationBellMeditationTimer.cpp +0 -4
@@ 83,8 83,4 @@ namespace app

        return handleAsyncResponse(resp);
    }

    // Empty: do not start idleTimer on application run
    void ApplicationBellMeditationTimer::onStart()
    {}
} // namespace app

M products/BellHybrid/apps/application-bell-meditation-timer/include/application-bell-meditation-timer/ApplicationBellMeditationTimer.hpp => products/BellHybrid/apps/application-bell-meditation-timer/include/application-bell-meditation-timer/ApplicationBellMeditationTimer.hpp +0 -3
@@ 41,9 41,6 @@ namespace app
        {
            return sys::ReturnCodes::Success;
        }

      private:
        void onStart() override;
    };

    template <> struct ManifestTraits<ApplicationBellMeditationTimer>

M products/BellHybrid/apps/application-bell-meditation-timer/presenter/IntervalChimePresenter.cpp => products/BellHybrid/apps/application-bell-meditation-timer/presenter/IntervalChimePresenter.cpp +2 -0
@@ 62,6 62,7 @@ namespace app::meditation
            if (option.second == value) {
                settings->setValue(
                    intervalDBRecordName, utils::to_string(option.first.count()), settings::SettingsScope::AppLocal);
                reinterpret_cast<app::Application *>(app)->suspendIdleTimer();
                app->switchWindow(gui::name::window::readyGoing);
                break;
            }


@@ 76,6 77,7 @@ namespace app::meditation
            utils::getNumericValue<int>(settings->getValue(meditationDBRecordName, settings::SettingsScope::AppLocal));
        if (duration == 1) {
            settings->setValue(intervalDBRecordName, utils::to_string(0), settings::SettingsScope::AppLocal);
            reinterpret_cast<app::Application *>(app)->suspendIdleTimer();
            app->switchWindow(gui::name::window::readyGoing);
            return;
        }

M products/BellHybrid/apps/application-bell-meditation-timer/presenter/MeditationProgressPresenter.cpp => products/BellHybrid/apps/application-bell-meditation-timer/presenter/MeditationProgressPresenter.cpp +1 -0
@@ 44,6 44,7 @@ namespace app::meditation

    void MeditationProgressPresenter::start()
    {
        reinterpret_cast<app::Application *>(app)->suspendIdleTimer();
        timer->reset(std::chrono::seconds(duration), std::chrono::seconds(interval));
        timer->start();
    }

M products/BellHybrid/apps/application-bell-meditation-timer/windows/MeditationRunningWindow.cpp => products/BellHybrid/apps/application-bell-meditation-timer/windows/MeditationRunningWindow.cpp +1 -0
@@ 126,6 126,7 @@ namespace gui
            return true;
        }
        if (inputEvent.isShortRelease(gui::KeyCode::KEY_RF)) {
            reinterpret_cast<app::Application *>(application)->resumeIdleTimer();
            presenter->abandon();
            return true;
        }

M products/BellHybrid/apps/application-bell-onboarding/windows/OnBoardingFinalizeWindow.cpp => products/BellHybrid/apps/application-bell-onboarding/windows/OnBoardingFinalizeWindow.cpp +3 -4
@@ 3,7 3,7 @@

#include "OnBoardingFinalizeWindow.hpp"

#include <Icon.hpp>
#include <gui/widgets/Icon.hpp>
#include <i18n/i18n.hpp>

namespace gui


@@ 38,8 38,7 @@ namespace gui
    {
        BellFinishedWindow::onBeforeShow(mode, data);

        icon->image->set("bell_very_big_logo", ImageTypeSpecifier::W_G);
        icon->text->setFont(style::window::font::verybiglight);
        icon->text->setText(utils::translate("app_bell_onboarding_finalize"));
        icon->image->set("circle_success_big");
        icon->setY(0);
    }
} // namespace gui

M products/BellHybrid/apps/application-bell-powernap/ApplicationBellPowerNap.cpp => products/BellHybrid/apps/application-bell-powernap/ApplicationBellPowerNap.cpp +5 -3
@@ 74,7 74,9 @@ namespace app
        return handleAsyncResponse(resp);
    }

    // Empty: do not start idleTimer on application run
    void ApplicationBellPowerNap::onStart()
    {}
    void ApplicationBellPowerNap::onStop()
    {
        Application::onStop();
        audioModel->stopPlayedByThis({});
    }
} // namespace app

M products/BellHybrid/apps/application-bell-powernap/include/application-bell-powernap/ApplicationBellPowerNap.hpp => products/BellHybrid/apps/application-bell-powernap/include/application-bell-powernap/ApplicationBellPowerNap.hpp +1 -3
@@ 24,6 24,7 @@ namespace app
    {
      private:
        std::unique_ptr<AbstractAudioModel> audioModel;
        void onStop() override;

      public:
        ApplicationBellPowerNap(std::string name                    = applicationBellPowerNapName,


@@ 44,9 45,6 @@ namespace app
        {
            return sys::ReturnCodes::Success;
        }

      private:
        void onStart() override;
    };

    template <> struct ManifestTraits<ApplicationBellPowerNap>

M products/BellHybrid/apps/application-bell-powernap/presenter/PowerNapMainWindowPresenter.cpp => products/BellHybrid/apps/application-bell-powernap/presenter/PowerNapMainWindowPresenter.cpp +1 -0
@@ 32,6 32,7 @@ namespace app::powernap
        const auto currentValue = model->getCurrentValue();
        settings->setValue(
            powernapDBRecordName, utils::to_string(currentValue.count()), settings::SettingsScope::AppLocal);
        reinterpret_cast<app::Application *>(app)->suspendIdleTimer();
        app->switchWindow(gui::window::name::powernapProgress);
    }
} // namespace app::powernap

M products/BellHybrid/apps/application-bell-powernap/presenter/PowerNapProgressPresenter.cpp => products/BellHybrid/apps/application-bell-powernap/presenter/PowerNapProgressPresenter.cpp +1 -1
@@ 65,7 65,7 @@ namespace app::powernap
    }
    void PowerNapProgressPresenter::onNapAlarmFinished()
    {
        audioModel.stop({});
        audioModel.stopPlayedByThis({});
        getView()->napEnded();
    }


M products/BellHybrid/apps/application-bell-powernap/windows/PowerNapProgressWindow.cpp => products/BellHybrid/apps/application-bell-powernap/windows/PowerNapProgressWindow.cpp +1 -0
@@ 109,6 109,7 @@ namespace gui
                return true;
            }
            else if (not presenter->isNapFinished() && key == KeyMap::Back) {
                reinterpret_cast<app::Application *>(application)->resumeIdleTimer();
                presenter->endNap();
                application->returnToPreviousWindow();
                return true;

M products/BellHybrid/apps/application-bell-settings/ApplicationBellSettings.cpp => products/BellHybrid/apps/application-bell-settings/ApplicationBellSettings.cpp +6 -0
@@ 239,4 239,10 @@ namespace app
        }
        return handleAsyncResponse(resp);
    }

    void ApplicationBellSettings::onStop()
    {
        Application::onStop();
        audioModel->stopPlayedByThis({});
    }
} // namespace app

M products/BellHybrid/apps/application-bell-settings/include/application-bell-settings/ApplicationBellSettings.hpp => products/BellHybrid/apps/application-bell-settings/include/application-bell-settings/ApplicationBellSettings.hpp +1 -0
@@ 29,6 29,7 @@ namespace app
    {
      private:
        std::unique_ptr<AbstractAudioModel> audioModel;
        void onStop() override;

      public:
        ApplicationBellSettings(std::string name                    = applicationBellSettingsName,

M products/BellHybrid/apps/application-bell-settings/include/application-bell-settings/models/TimeUnitsModel.hpp => products/BellHybrid/apps/application-bell-settings/include/application-bell-settings/models/TimeUnitsModel.hpp +1 -1
@@ 63,7 63,7 @@ namespace app::bell_settings
        auto loadData() -> void override;

      private:
        static constexpr int factoryResetTime    = 12; // noon
        static constexpr int factoryResetTime    = 12 * 60 * 60; // 12:00 PM
        static constexpr auto factoryRestTimeFmt = utils::time::Locale::TimeFormat::FormatTime12H;
    };
} // 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 +6 -5
@@ 28,11 28,12 @@ namespace app::bell_settings
    {
        auto chimeIntervals = getDefaultChimeIntervalRange();

        chimeIntervals.erase(
            std::remove_if(chimeIntervals.begin() + 1,
                           chimeIntervals.end(),
                           [chimeLength](const auto &e) { return e.getValue().value() >= chimeLength; }),
            chimeIntervals.end());
        chimeIntervals.erase(std::remove_if(chimeIntervals.begin(),
                                            chimeIntervals.end(),
                                            [chimeLength](const auto &e) {
                                                return e.getValue() && (e.getValue().value() >= chimeLength);
                                            }),
                             chimeIntervals.end());

        return chimeIntervals;
    }

M products/BellHybrid/apps/application-bell-settings/presenter/BedtimeSettingsPresenter.cpp => products/BellHybrid/apps/application-bell-settings/presenter/BedtimeSettingsPresenter.cpp +1 -1
@@ 61,7 61,7 @@ namespace app::bell_settings

    void BedtimeSettingsPresenter::stopSound()
    {
        this->audioModel.stop({});
        this->audioModel.stopPlayedByThis({});
    }
    void BedtimeSettingsPresenter::exitWithoutSave()
    {

M products/BellHybrid/apps/application-bell-settings/presenter/alarm_settings/AlarmSettingsPresenter.cpp => products/BellHybrid/apps/application-bell-settings/presenter/alarm_settings/AlarmSettingsPresenter.cpp +1 -1
@@ 57,7 57,7 @@ namespace app::bell_settings
    }
    void AlarmSettingsPresenter::stopSound()
    {
        this->audioModel.stop({});
        this->audioModel.stopPlayedByThis({});
    }
    void AlarmSettingsPresenter::exitWithoutSave()
    {

M products/BellHybrid/apps/application-bell-settings/presenter/alarm_settings/PrewakeUpPresenter.cpp => products/BellHybrid/apps/application-bell-settings/presenter/alarm_settings/PrewakeUpPresenter.cpp +1 -1
@@ 61,7 61,7 @@ namespace app::bell_settings
    }
    void PrewakeUpWindowPresenter::stopSound()
    {
        this->audioModel.stop({});
        this->audioModel.stopPlayedByThis({});
    }
    void PrewakeUpWindowPresenter::exitWithoutSave()
    {

M products/BellHybrid/apps/application-bell-settings/presenter/alarm_settings/SnoozePresenter.cpp => products/BellHybrid/apps/application-bell-settings/presenter/alarm_settings/SnoozePresenter.cpp +1 -1
@@ 58,7 58,7 @@ namespace app::bell_settings
    }
    void SnoozePresenter::stopSound()
    {
        audioModel.stop({});
        audioModel.stopPlayedByThis({});
    }
    void SnoozePresenter::eraseProviderData()
    {

M products/BellHybrid/apps/common/include/common/models/AbstractAudioModel.hpp => products/BellHybrid/apps/common/include/common/models/AbstractAudioModel.hpp +2 -1
@@ 36,7 36,8 @@ namespace app
        virtual std::optional<Volume> getVolume(PlaybackType playbackType)                                  = 0;
        virtual void getVolume(PlaybackType playbackType, OnGetValueCallback &&callback)                    = 0;
        virtual void play(const std::string &filePath, PlaybackType type, OnStateChangeCallback &&callback) = 0;
        virtual void stop(OnStateChangeCallback &&callback)                                                 = 0;
        virtual void stopAny(OnStateChangeCallback &&callback)                                              = 0;
        virtual void stopPlayedByThis(OnStateChangeCallback &&callback)                                     = 0;
        virtual void pause(OnStateChangeCallback &&callback)                                                = 0;
        virtual void resume(OnStateChangeCallback &&callback)                                               = 0;
        virtual void setPlaybackFinishedCb(OnPlaybackFinishedCallback &&callback)                           = 0;

M products/BellHybrid/apps/common/include/common/models/AudioModel.hpp => products/BellHybrid/apps/common/include/common/models/AudioModel.hpp +4 -1
@@ 18,13 18,16 @@ namespace app
        std::optional<Volume> getVolume(PlaybackType playbackType) override;
        void getVolume(PlaybackType playbackType, OnGetValueCallback &&callback) override;
        void play(const std::string &filePath, PlaybackType type, OnStateChangeCallback &&callback) override;
        void stop(OnStateChangeCallback &&callback) override;
        void stopAny(OnStateChangeCallback &&callback) override;
        void stopPlayedByThis(OnStateChangeCallback &&callback) override;
        void pause(OnStateChangeCallback &&callback) override;
        void resume(OnStateChangeCallback &&callback) override;
        void setPlaybackFinishedCb(OnPlaybackFinishedCallback &&callback) override;
        bool hasPlaybackFinished() override;

      private:
        audio::Token lastPlayedToken = audio::Token::MakeBadToken();
        void stop(audio::Token token, OnStateChangeCallback &&callback);
        std::function<void()> playbackFinishedCallback{nullptr};
        bool playbackFinishedFlag{false};
        ApplicationCommon *app{};

M products/BellHybrid/apps/common/src/AudioModel.cpp => products/BellHybrid/apps/common/src/AudioModel.cpp +15 -4
@@ 76,8 76,9 @@ namespace app
        playbackFinishedFlag = false;
        auto msg  = std::make_unique<service::AudioStartPlaybackRequest>(filePath, convertPlaybackType(type));
        auto task = app::AsyncRequest::createFromMessage(std::move(msg), service::audioServiceName);
        auto cb   = [_callback = callback](auto response) {
            auto result = dynamic_cast<service::AudioStartPlaybackResponse *>(response);
        auto cb              = [_callback = callback, this](auto response) {
            auto result     = dynamic_cast<service::AudioStartPlaybackResponse *>(response);
            lastPlayedToken = result->token;
            if (result == nullptr) {
                return false;
            }


@@ 91,9 92,14 @@ namespace app
        task->execute(app, this, std::move(cb));
    }

    void AudioModel::stop(OnStateChangeCallback &&callback)
    void AudioModel::stopAny(OnStateChangeCallback &&callback)
    {
        stop(audio::Token(), std::move(callback));
    }

    void AudioModel::stop(audio::Token token, OnStateChangeCallback &&callback)
    {
        auto msg  = std::make_unique<service::AudioStopRequest>();
        auto msg  = std::make_unique<service::AudioStopRequest>(token);
        auto task = app::AsyncRequest::createFromMessage(std::move(msg), service::audioServiceName);
        auto cb   = [_callback = callback](auto response) {
            auto result = dynamic_cast<service::AudioStopResponse *>(response);


@@ 109,6 115,11 @@ namespace app
        task->execute(app, this, std::move(cb));
    }

    void AudioModel::stopPlayedByThis(OnStateChangeCallback &&callback)
    {
        stop(lastPlayedToken, std::move(callback));
    }

    void AudioModel::setVolume(AbstractAudioModel::Volume volume,
                               PlaybackType playbackType,
                               OnStateChangeCallback &&callback)

M products/BellHybrid/apps/include/Application.hpp => products/BellHybrid/apps/include/Application.hpp +4 -1
@@ 11,6 11,8 @@ namespace app
    {
      public:
        using ApplicationCommon::ApplicationCommon;
        void resumeIdleTimer();
        void suspendIdleTimer();

      protected:
        void attachPopups(const std::vector<gui::popup::ID> &popupsList) override;


@@ 19,6 21,7 @@ namespace app
        void restartIdleTimer();
        void stopIdleTimer();
        void stopAllAudio();
        virtual void onStop();

      private:
        sys::MessagePointer handleKBDKeyEvent(sys::Message *msgl) override;


@@ 29,6 32,6 @@ namespace app

        virtual void onKeyPressed();
        virtual void onStart();
        virtual void onStop();
        bool idleTimerActiveFlag = true;
    };
} // namespace app

M products/BellHybrid/services/audio/ServiceAudio.cpp => products/BellHybrid/services/audio/ServiceAudio.cpp +11 -4
@@ 12,6 12,8 @@ namespace
{
    constexpr auto stackSize            = 1024 * 4;
    constexpr auto defaultVolume        = "5";
    constexpr auto defaultSnoozeVolume  = "4";
    constexpr auto defaultBedtimeVolume = "6";
    constexpr audio::Volume maxInVolume = 10;
    constexpr audio::Volume minVolume   = 0;
    constexpr auto profileType          = audio::Profile::Type::PlaybackLoudspeaker;


@@ 23,9 25,9 @@ namespace
            {DbPathElement{Setting::Volume, PlaybackType::Meditation, Profile::Type::PlaybackLoudspeaker},defaultVolume},
            {DbPathElement{Setting::Volume, PlaybackType::Multimedia, Profile::Type::PlaybackLoudspeaker},defaultVolume},
            {DbPathElement{Setting::Volume, PlaybackType::Alarm, Profile::Type::PlaybackLoudspeaker}, defaultVolume},
            {DbPathElement{Setting::Volume, PlaybackType::Bedtime, Profile::Type::PlaybackLoudspeaker}, defaultVolume},
            {DbPathElement{Setting::Volume, PlaybackType::PreWakeUp, Profile::Type::PlaybackLoudspeaker},defaultVolume},
            {DbPathElement{Setting::Volume, PlaybackType::Snooze, Profile::Type::PlaybackLoudspeaker}, defaultVolume},
            {DbPathElement{Setting::Volume, PlaybackType::Bedtime, Profile::Type::PlaybackLoudspeaker}, defaultBedtimeVolume},
            {DbPathElement{Setting::Volume, PlaybackType::PreWakeUp, Profile::Type::PlaybackLoudspeaker},defaultSnoozeVolume},
            {DbPathElement{Setting::Volume, PlaybackType::Snooze, Profile::Type::PlaybackLoudspeaker}, defaultSnoozeVolume},

            /// Profiles below are not used but unfortunately, must exist in order to satisfy audio module requirements
            {DbPathElement{Setting::Volume, PlaybackType::Meditation, Profile::Type::PlaybackHeadphones},defaultVolume},


@@ 155,7 157,12 @@ namespace service

        for (auto &input : audioMux.GetAllInputs()) {
            auto t = input.token;
            retCodes.emplace_back(t, stopInput(&input));
            if (token.IsValid() && t == token) {
                retCodes.emplace_back(t, stopInput(&input));
            }
            if (token.IsUninitialized()) {
                retCodes.emplace_back(t, stopInput(&input));
            }
        }

        // on failure return first false code

M products/BellHybrid/services/evtmgr/EventManager.cpp => products/BellHybrid/services/evtmgr/EventManager.cpp +4 -0
@@ 55,6 55,10 @@ void EventManager::handleKeyEvent(sys::Message *msg)
    if (kbdMessage == nullptr) {
        return;
    }
    if (kbdMessage->key.keyCode == bsp::KeyCodes::JoystickEnter) {
        // Power key notification
        bus.sendUnicast(std::make_shared<sevm::KbdMessage>(), service::name::system_manager);
    }

    if (kbdMessage->key.state == RawKey::State::Pressed || kbdMessage->key.state == RawKey::State::Moved) {
        userActivityHandler.handleUserInput();

M products/BellHybrid/services/time/AlarmOperations.cpp => products/BellHybrid/services/time/AlarmOperations.cpp +19 -18
@@ 152,7 152,7 @@ namespace alarms
          bedtime(std::move(bedtimeSettingsProvider))
    {}

    bool AlarmOperations::minuteUpdated(TimePoint now)
    void AlarmOperations::minuteUpdated(TimePoint now)
    {
        /**
         * A very simple alarm priority:


@@ 163,15 163,11 @@ namespace alarms
         * By design, there is no possibility to have both the main alarm, pre wakeup, and snooze alarm set for the same
         * timestamp hence it is safe to process these three in the one go.
         */
        auto wasAlarmConsumed = AlarmOperationsCommon::minuteUpdated(now);
        wasAlarmConsumed |= processPreWakeUp(now);
        wasAlarmConsumed |= processSnoozeChime(now);

        if (not wasAlarmConsumed) {
        AlarmOperationsCommon::minuteUpdated(now);
        processPreWakeUp(now);
        if (isBedtimeAllowed()) {
            processBedtime(now);
        }

        return false;
    }

    void AlarmOperations::stopAllSnoozedAlarms()


@@ 180,22 176,22 @@ namespace alarms
        AlarmOperationsCommon::stopAllSnoozedAlarms();
    }

    bool AlarmOperations::processPreWakeUp(TimePoint now)
    void AlarmOperations::processPreWakeUp(TimePoint now)
    {
        if (nextSingleEvents.empty()) {
            return false;
            return;
        }

        auto nextEvent = getNextPreWakeUpEvent();
        if (!nextEvent.isValid()) {
            return false;
            return;
        }

        const auto decision = preWakeUp.decide(now, nextEvent);
        if (!decision.timeForChime && !decision.timeForFrontlight) {
            return false;
            return;
        }
        return handlePreWakeUp(nextEvent, decision);
        handlePreWakeUp(nextEvent, decision);
    }

    void AlarmOperations::processBedtime(TimePoint now)


@@ 224,20 220,16 @@ namespace alarms
        return event;
    }

    bool AlarmOperations::handlePreWakeUp(const SingleEventRecord &event, PreWakeUp::Decision decision)
    void AlarmOperations::handlePreWakeUp(const SingleEventRecord &event, PreWakeUp::Decision decision)
    {
        auto ret = false;
        if (auto alarmEventPtr = std::dynamic_pointer_cast<AlarmEventRecord>(event.parent); alarmEventPtr) {
            if (decision.timeForChime) {
                handleAlarmEvent(alarmEventPtr, alarms::AlarmType::PreWakeUpChime, true);
                ret = true;
            }
            if (decision.timeForFrontlight) {
                handleAlarmEvent(alarmEventPtr, alarms::AlarmType::PreWakeUpFrontlight, true);
                ret = true;
            }
        }
        return ret;
    }

    bool AlarmOperations::processSnoozeChime(TimePoint now)


@@ 287,6 279,10 @@ namespace alarms
        handleAlarmEvent(event, alarms::AlarmType::PreWakeUpChime, false);
        handleAlarmEvent(event, alarms::AlarmType::PreWakeUpFrontlight, false);
    }
    bool AlarmOperations::isBedtimeAllowed() const
    {
        return ongoingSingleEvents.empty() && not preWakeUp.isActive();
    }

    PreWakeUp::PreWakeUp(std::unique_ptr<PreWakeUpSettingsProvider> &&settingsProvider)
        : settingsProvider{std::move(settingsProvider)}


@@ 298,6 294,7 @@ namespace alarms
        const auto frontlightSettings  = settingsProvider->getFrontlightSettings();
        const auto isTimeForChime      = isTimeForPreWakeUp(now, event, chimeSettings);
        const auto isTimeForFrontlight = isTimeForPreWakeUp(now, event, frontlightSettings);
        active                         = isTimeForChime || isTimeForFrontlight;
        return {isTimeForChime, isTimeForFrontlight};
    }



@@ 308,6 305,10 @@ namespace alarms
        const auto expectedAlarmStart = std::chrono::floor<std::chrono::minutes>(now) + settings.timeBeforeAlarm;
        return settings.enabled && std::chrono::floor<std::chrono::minutes>(event.startDate) == expectedAlarmStart;
    }
    auto PreWakeUp::isActive() const -> bool
    {
        return active;
    }

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

M products/BellHybrid/services/time/include/time/AlarmOperations.hpp => products/BellHybrid/services/time/include/time/AlarmOperations.hpp +7 -3
@@ 64,6 64,7 @@ namespace alarms

        explicit PreWakeUp(std::unique_ptr<PreWakeUpSettingsProvider> &&settingsProvider);
        auto decide(TimePoint now, const SingleEventRecord &event) -> Decision;
        auto isActive() const -> bool;

      private:
        auto isTimeForPreWakeUp(TimePoint now,


@@ 71,6 72,7 @@ namespace alarms
                                PreWakeUpSettingsProvider::Settings settings) -> bool;

        std::unique_ptr<PreWakeUpSettingsProvider> settingsProvider;
        bool active{false};
    };

    class Bedtime


@@ 95,19 97,21 @@ namespace alarms
                        std::unique_ptr<AbstractBedtimeSettingsProvider> &&BedtimeModel);

      private:
        bool minuteUpdated(TimePoint now) override;
        void minuteUpdated(TimePoint now) override;
        void stopAllSnoozedAlarms() override;
        bool processPreWakeUp(TimePoint now);
        void processPreWakeUp(TimePoint now);
        bool processSnoozeChime(TimePoint now);
        void stopAllSnoozeChimes();

        SingleEventRecord getNextPreWakeUpEvent();
        bool handlePreWakeUp(const SingleEventRecord &event, PreWakeUp::Decision decision);
        void handlePreWakeUp(const SingleEventRecord &event, PreWakeUp::Decision decision);
        void handleSnoozeChime(const SingleEventRecord &event, bool newStateOn);
        void handleBedtime(const SingleEventRecord &event, bool decision);
        void processBedtime(TimePoint now);
        void onAlarmTurnedOff(const std::shared_ptr<AlarmEventRecord> &event, alarms::AlarmType alarmType) override;

        bool isBedtimeAllowed() const;

        PreWakeUp preWakeUp;
        std::unique_ptr<SnoozeChimeSettingsProvider> snoozeChimeSettings;
        Bedtime bedtime;

M products/PurePhone/services/evtmgr/EventManager.cpp => products/PurePhone/services/evtmgr/EventManager.cpp +6 -0
@@ 166,6 166,12 @@ void EventManager::handleKeyEvent(sys::Message *msg)
    EventManagerCommon::handleKeyEvent(msg);

    auto kbdMessage = dynamic_cast<sevm::KbdMessage *>(msg);
    if (kbdMessage->key.state == RawKey::State::Pressed) {
        if (kbdMessage->key.keyCode == bsp::KeyCodes::FnRight) {
            // Power key notification
            bus.sendUnicast(std::make_shared<sevm::KbdMessage>(), service::name::system_manager);
        }
    }

    if (kbdMessage->key.state == RawKey::State::Pressed) {
        backlightHandler.handleKeyPressed(kbdMessage->key.keyCode);

M products/PurePhone/services/time/AlarmOperations.cpp => products/PurePhone/services/time/AlarmOperations.cpp +1 -1
@@ 25,7 25,7 @@ namespace alarms
        : AlarmOperationsCommon{std::move(alarmEventsRepo), std::move(getCurrentTimeCallback)}
    {}

    bool AlarmOperations::minuteUpdated(TimePoint now)
    void AlarmOperations::minuteUpdated(TimePoint now)
    {
        return AlarmOperationsCommon::minuteUpdated(now);
    }

M products/PurePhone/services/time/include/time/AlarmOperations.hpp => products/PurePhone/services/time/include/time/AlarmOperations.hpp +1 -1
@@ 22,7 22,7 @@ namespace alarms
        AlarmOperations(std::unique_ptr<AbstractAlarmEventsRepository> &&alarmEventsRepo,
                        GetCurrentTime getCurrentTimeCallback);

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

      private:
    };