From 8c53ac5fc2a658780685aa98983f692bd8f8e153 Mon Sep 17 00:00:00 2001 From: mkamonMdt Date: Wed, 8 Sep 2021 20:05:33 +0200 Subject: [PATCH] [BH-851] PowerNap alarms implementation The following commit provides an implementation to an PowerNap's alarm, that provides appropriate abstraction for an alarm mechanics. As the PowerNap's alarm can be active only on the application, the implementation does not make use of Bell's AlarmHandlers. --- .../ApplicationBellPowerNap.cpp | 14 ++++++- .../application-bell-powernap/CMakeLists.txt | 2 + .../ApplicationBellPowerNap.hpp | 9 ++++- .../models/PowerNapModel.cpp | 2 +- .../presenter/PowerNapProgressPresenter.cpp | 25 +++++++++---- .../presenter/PowerNapProgressPresenter.hpp | 10 ++++- .../widgets/PowerNapAlarm.cpp | 37 +++++++++++++++++++ .../widgets/PowerNapAlarm.hpp | 36 ++++++++++++++++++ .../windows/PowerNapProgressWindow.cpp | 5 ++- .../windows/PowerNapProgressWindow.hpp | 2 +- 10 files changed, 126 insertions(+), 16 deletions(-) create mode 100644 products/BellHybrid/apps/application-bell-powernap/widgets/PowerNapAlarm.cpp create mode 100644 products/BellHybrid/apps/application-bell-powernap/widgets/PowerNapAlarm.hpp diff --git a/products/BellHybrid/apps/application-bell-powernap/ApplicationBellPowerNap.cpp b/products/BellHybrid/apps/application-bell-powernap/ApplicationBellPowerNap.cpp index dde8d6aceec427c9288a75f80ffbf9696638d5dc..7fc1962bb6910dcc15bc11adcfbcbb3e3223f508 100644 --- a/products/BellHybrid/apps/application-bell-powernap/ApplicationBellPowerNap.cpp +++ b/products/BellHybrid/apps/application-bell-powernap/ApplicationBellPowerNap.cpp @@ -5,9 +5,11 @@ #include "presenter/PowerNapMainWindowPresenter.hpp" #include "presenter/PowerNapProgressPresenter.hpp" #include "presenter/PowerNapSessionEndedPresenter.hpp" +#include "widgets/PowerNapAlarm.hpp" #include "windows/PowerNapMainWindow.hpp" #include "windows/PowerNapProgressWindow.hpp" #include "windows/PowerNapSessionEndedWindow.hpp" +#include namespace app { @@ -16,9 +18,11 @@ namespace app sys::phone_modes::PhoneMode mode, sys::bluetooth::BluetoothMode bluetoothMode, StartInBackground startInBackground) - : ApplicationBell(std::move(name), std::move(parent), mode, bluetoothMode, startInBackground) + : ApplicationBell(std::move(name), std::move(parent), mode, bluetoothMode, startInBackground), + alarm{std::make_unique(this)} {} + ApplicationBellPowerNap::~ApplicationBellPowerNap() = default; sys::ReturnCodes ApplicationBellPowerNap::InitHandler() { auto ret = Application::InitHandler(); @@ -37,7 +41,7 @@ namespace app return std::make_unique(app, std::move(presenter)); }); windowsFactory.attach(gui::window::name::powernapProgress, [this](Application *app, const std::string &name) { - auto presenter = std::make_unique(app, settings.get()); + auto presenter = std::make_unique(app, settings.get(), *alarm); return std::make_unique(app, std::move(presenter)); }); windowsFactory.attach(gui::window::name::powernapSessionEnded, [](Application *app, const std::string &name) { @@ -55,6 +59,12 @@ namespace app response != nullptr && response->retCode == sys::ReturnCodes::Success) { return retMsg; } + + if ((resp != nullptr) && typeid(*resp) == typeid(AudioStartPlaybackResponse)) { + auto *msg = static_cast(resp); + alarm->registerAudioStream(msg->token); + } + return sys::msgHandled(); } } // namespace app diff --git a/products/BellHybrid/apps/application-bell-powernap/CMakeLists.txt b/products/BellHybrid/apps/application-bell-powernap/CMakeLists.txt index 6fd873950b701ef57206759338ae5cc9d279da49..cc95341030ec43a86ad9019d64801e84c594ea7d 100644 --- a/products/BellHybrid/apps/application-bell-powernap/CMakeLists.txt +++ b/products/BellHybrid/apps/application-bell-powernap/CMakeLists.txt @@ -19,6 +19,7 @@ target_sources(application-bell-powernap presenter/PowerNapMainWindowPresenter.cpp presenter/PowerNapProgressPresenter.cpp presenter/PowerNapSessionEndedPresenter.cpp + widgets/PowerNapAlarm.cpp windows/PowerNapMainWindow.cpp windows/PowerNapProgressWindow.cpp windows/PowerNapSessionEndedWindow.cpp @@ -28,6 +29,7 @@ target_sources(application-bell-powernap presenter/PowerNapMainWindowPresenter.hpp presenter/PowerNapProgressPresenter.hpp presenter/PowerNapSessionEndedPresenter.hpp + widgets/PowerNapAlarm.hpp windows/PowerNapMainWindow.hpp windows/PowerNapProgressWindow.hpp windows/PowerNapSessionEndedWindow.hpp diff --git a/products/BellHybrid/apps/application-bell-powernap/include/application-bell-powernap/ApplicationBellPowerNap.hpp b/products/BellHybrid/apps/application-bell-powernap/include/application-bell-powernap/ApplicationBellPowerNap.hpp index 6cdd15cc968fd5362c82fd829fc8c1ba1b97b08e..550d57204828ea329ba16d2467a6bfc2207fa1e1 100644 --- a/products/BellHybrid/apps/application-bell-powernap/include/application-bell-powernap/ApplicationBellPowerNap.hpp +++ b/products/BellHybrid/apps/application-bell-powernap/include/application-bell-powernap/ApplicationBellPowerNap.hpp @@ -12,17 +12,24 @@ namespace gui::window::name } namespace app { + namespace powernap + { + class PowerNapAlarmImpl; + } + inline constexpr auto applicationBellPowerNapName = "ApplicationBellPowerNap"; class ApplicationBellPowerNap : public ApplicationBell { + std::unique_ptr alarm; + public: ApplicationBellPowerNap(std::string name = applicationBellPowerNapName, std::string parent = "", sys::phone_modes::PhoneMode mode = sys::phone_modes::PhoneMode::Offline, sys::bluetooth::BluetoothMode bluetoothMode = sys::bluetooth::BluetoothMode::Disabled, StartInBackground startInBackground = {false}); - + ~ApplicationBellPowerNap(); sys::ReturnCodes InitHandler() override; void createUserInterface() override; diff --git a/products/BellHybrid/apps/application-bell-powernap/models/PowerNapModel.cpp b/products/BellHybrid/apps/application-bell-powernap/models/PowerNapModel.cpp index 2957bab74c5786d4166ded8efd2f86b4fb0eefbc..508060d8b6ddf0fcc4d7a5cc435127d559e98f86 100644 --- a/products/BellHybrid/apps/application-bell-powernap/models/PowerNapModel.cpp +++ b/products/BellHybrid/apps/application-bell-powernap/models/PowerNapModel.cpp @@ -9,7 +9,7 @@ namespace { constexpr std::chrono::minutes emptyValue{0}; - constexpr std::chrono::minutes spinnerDefaultValue{20}; + constexpr std::chrono::minutes spinnerDefaultValue{15}; } // namespace namespace app::powernap diff --git a/products/BellHybrid/apps/application-bell-powernap/presenter/PowerNapProgressPresenter.cpp b/products/BellHybrid/apps/application-bell-powernap/presenter/PowerNapProgressPresenter.cpp index 8e373fe927478aef346c6dda51883515e94e1bfd..6f5b85349cf0ca624c744263bfdbc9bf3fa4b4c6 100644 --- a/products/BellHybrid/apps/application-bell-powernap/presenter/PowerNapProgressPresenter.cpp +++ b/products/BellHybrid/apps/application-bell-powernap/presenter/PowerNapProgressPresenter.cpp @@ -4,6 +4,7 @@ #include "PowerNapProgressPresenter.hpp" #include "application-bell-powernap/ApplicationBellPowerNap.hpp" #include "data/PowerNapCommon.hpp" +#include "widgets/PowerNapAlarm.hpp" #include #include @@ -21,12 +22,14 @@ namespace } // namespace namespace app::powernap { - PowerNapProgressPresenter::PowerNapProgressPresenter(app::Application *app, settings::Settings *settings) - : app{app}, settings{settings}, napAlarmTimer{sys::TimerFactory::createSingleShotTimer( - app, powernapAlarmTimerName, powernapAlarmTimeout, [this](sys::Timer &) { - onNapAlarmFinished(); - })} + PowerNapProgressPresenter::PowerNapProgressPresenter(app::Application *app, + settings::Settings *settings, + PowerNapAlarm &alarm) + : app{app}, settings{settings}, alarm{alarm}, + napAlarmTimer{sys::TimerFactory::createSingleShotTimer( + app, powernapAlarmTimerName, powernapAlarmTimeout, [this](sys::Timer &) { onNapAlarmFinished(); })} {} + void PowerNapProgressPresenter::initTimer(gui::Item *parent) { timer = std::make_unique(app, parent, powernapTimerName, timerTick); @@ -39,6 +42,12 @@ namespace app::powernap timer->reset(std::chrono::minutes{utils::getNumericValue(value)}); timer->start(); } + void PowerNapProgressPresenter::endNap() + { + timer->stop(); + napAlarmTimer.stop(); + onNapAlarmFinished(); + } app::ProgressTimerUIConfigurator &PowerNapProgressPresenter::getUIConfigurator() noexcept { Expects(timer != nullptr); @@ -46,11 +55,13 @@ namespace app::powernap } void PowerNapProgressPresenter::onNapFinished() { + alarm.start(); napAlarmTimer.start(); } - void PowerNapProgressPresenter::onNapAlarmFinished() { - getView()->switchWindow(); + alarm.stop(); + getView()->napEnded(); } + } // namespace app::powernap diff --git a/products/BellHybrid/apps/application-bell-powernap/presenter/PowerNapProgressPresenter.hpp b/products/BellHybrid/apps/application-bell-powernap/presenter/PowerNapProgressPresenter.hpp index 9ae82095f658b831d97a4f7d52e1cf360ec133a4..df6822c5153683a358a4e0dafadb5eafe764bbb7 100644 --- a/products/BellHybrid/apps/application-bell-powernap/presenter/PowerNapProgressPresenter.hpp +++ b/products/BellHybrid/apps/application-bell-powernap/presenter/PowerNapProgressPresenter.hpp @@ -22,6 +22,7 @@ namespace settings namespace app::powernap { + class PowerNapAlarm; class PowerNapProgressContract { public: @@ -29,7 +30,7 @@ namespace app::powernap { public: ~View() = default; - virtual void switchWindow() = 0; + virtual void napEnded() = 0; }; class Presenter : public BasePresenter @@ -38,24 +39,29 @@ namespace app::powernap virtual void initTimer(gui::Item *parent) = 0; virtual app::ProgressTimerUIConfigurator &getUIConfigurator() noexcept = 0; virtual void activate() = 0; + virtual void endNap() = 0; }; }; + class AlarmController; + class PowerNapProgressPresenter : public PowerNapProgressContract::Presenter { app::Application *app = nullptr; settings::Settings *settings = nullptr; + PowerNapAlarm &alarm; std::unique_ptr timer; sys::TimerHandle napAlarmTimer; void initTimer(gui::Item *parent) override; app::ProgressTimerUIConfigurator &getUIConfigurator() noexcept override; void activate() override; + void endNap() override; void onNapFinished(); void onNapAlarmFinished(); public: - PowerNapProgressPresenter(app::Application *app, settings::Settings *settings); + PowerNapProgressPresenter(app::Application *app, settings::Settings *settings, PowerNapAlarm &alarm); }; } // namespace app::powernap diff --git a/products/BellHybrid/apps/application-bell-powernap/widgets/PowerNapAlarm.cpp b/products/BellHybrid/apps/application-bell-powernap/widgets/PowerNapAlarm.cpp new file mode 100644 index 0000000000000000000000000000000000000000..0fe02b4a434a5a6431c75681f3dc52be39e18a02 --- /dev/null +++ b/products/BellHybrid/apps/application-bell-powernap/widgets/PowerNapAlarm.cpp @@ -0,0 +1,37 @@ +// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved. +// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md + +#include "PowerNapAlarm.hpp" + +#include +#include + +namespace +{ + constexpr auto alarmAudioPath = "assets/audio/alarm/alarm_mudita_bell.mp3"; +} + +namespace app::powernap +{ + PowerNapAlarmImpl::PowerNapAlarmImpl(app::Application *app) : app{app} + {} + + void PowerNapAlarmImpl::start() + { + AudioServiceAPI::PlaybackStart( + app, audio::PlaybackType::Alarm, purefs::dir::getCurrentOSPath() / alarmAudioPath); + } + + void PowerNapAlarmImpl::stop() + { + if (token.IsValid()) { + AudioServiceAPI::Stop(app, token); + token = audio::Token::MakeBadToken(); + } + } + + void PowerNapAlarmImpl::registerAudioStream(audio::Token _token) + { + token = _token; + } +} // namespace app::powernap diff --git a/products/BellHybrid/apps/application-bell-powernap/widgets/PowerNapAlarm.hpp b/products/BellHybrid/apps/application-bell-powernap/widgets/PowerNapAlarm.hpp new file mode 100644 index 0000000000000000000000000000000000000000..66647037d2387b5d14e11cf70252da294ad76e8a --- /dev/null +++ b/products/BellHybrid/apps/application-bell-powernap/widgets/PowerNapAlarm.hpp @@ -0,0 +1,36 @@ +// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved. +// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md + +#pragma once +#include + +namespace app +{ + class Application; +} + +namespace app::powernap +{ + class PowerNapAlarm + { + public: + virtual ~PowerNapAlarm() = default; + + virtual void start() = 0; + virtual void stop() = 0; + }; + + class PowerNapAlarmImpl : public PowerNapAlarm + { + app::Application *app{}; + audio::Token token; + + void start() override; + void stop() override; + + public: + explicit PowerNapAlarmImpl(app::Application *app); + void registerAudioStream(audio::Token _token); + }; + +} // namespace app::powernap diff --git a/products/BellHybrid/apps/application-bell-powernap/windows/PowerNapProgressWindow.cpp b/products/BellHybrid/apps/application-bell-powernap/windows/PowerNapProgressWindow.cpp index 08840447515b4b7f8909094f3e28258f54827036..d3f6064fa723bcf518f83600937e4d596253aefd 100644 --- a/products/BellHybrid/apps/application-bell-powernap/windows/PowerNapProgressWindow.cpp +++ b/products/BellHybrid/apps/application-bell-powernap/windows/PowerNapProgressWindow.cpp @@ -54,6 +54,7 @@ namespace gui : AppWindow(app, gui::window::name::powernapProgress), presenter{std::move(presenter)} { buildInterface(); + this->presenter->attach(this); } void PowerNapProgressWindow::onBeforeShow(ShowMode mode, SwitchData *data) @@ -93,13 +94,13 @@ namespace gui { if (inputEvent.isShortRelease()) { if (inputEvent.is(KeyCode::KEY_RF) || inputEvent.is(KeyCode::KEY_ENTER)) { - switchWindow(); + presenter->endNap(); return true; } } return AppWindow::onInput(inputEvent); } - void PowerNapProgressWindow::switchWindow() + void PowerNapProgressWindow::napEnded() { application->switchWindow(gui::window::name::powernapSessionEnded, std::make_unique()); } diff --git a/products/BellHybrid/apps/application-bell-powernap/windows/PowerNapProgressWindow.hpp b/products/BellHybrid/apps/application-bell-powernap/windows/PowerNapProgressWindow.hpp index e17eb21ccdfab62b55b3295092c064e6b2fc995f..aef4ffb2640e2b6f41c232ee1d1d1c7cdd625b20 100644 --- a/products/BellHybrid/apps/application-bell-powernap/windows/PowerNapProgressWindow.hpp +++ b/products/BellHybrid/apps/application-bell-powernap/windows/PowerNapProgressWindow.hpp @@ -23,7 +23,7 @@ namespace gui void buildLayout(); void configureTimer(); - void switchWindow() override; + void napEnded() override; public: PowerNapProgressWindow(app::Application *app,