From 39718a08ea04ef45f50794117a7edfec6ddae023 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Ta=C5=84ski?= Date: Fri, 8 Oct 2021 17:24:18 +0200 Subject: [PATCH] [BH-903] Pre-wake up frontlight Implemented a frontlight handling for the pre-wake up. Major clean-up of the frontlight implementation. --- .../bsp/eink_frontlight/eink_frontlight.cpp | 4 +- module-db/Interface/EventRecord.cpp | 5 + module-db/Interface/EventRecord.hpp | 2 + .../BacklightHandlerCommon.cpp | 36 ++--- .../BacklightHandlerCommon.hpp | 15 +- .../screen-light-control/ControlFunctions.cpp | 14 ++ .../screen-light-control/ControlFunctions.hpp | 13 ++ .../ScreenLightControl.hpp | 48 ++----- .../ScreenLightControlParameters.cpp | 6 + .../ScreenLightControlParameters.hpp | 32 ++++- .../ScreenLightControlMessage.hpp | 27 +++- .../service-time/AlarmOperations.cpp | 5 + .../service-time/AlarmOperations.hpp | 1 + .../BellHybrid/alarms/BellAlarmHandler.cpp | 13 +- products/BellHybrid/alarms/CMakeLists.txt | 1 + .../alarms/include/BellAlarmHandler.hpp | 9 ++ .../alarms/src/actions/FrontlightAction.cpp | 118 ++++++++++++++- .../alarms/src/actions/FrontlightAction.hpp | 11 +- .../BellHybrid/services/evtmgr/CMakeLists.txt | 1 + .../services/evtmgr/EventManager.cpp | 12 +- .../backlight-handler/BacklightHandler.cpp | 52 ++++--- .../backlight-handler/BacklightHandler.hpp | 37 ----- .../evtmgr/include/evtmgr/EventManager.hpp | 2 +- .../BacklightHandler.hpp | 12 +- .../ScreenLightControl.cpp | 134 +++++++++++------- .../ScreenLightControl.hpp | 71 ++++++++++ .../services/time/AlarmOperations.cpp | 34 ++++- .../time/include/time/AlarmOperations.hpp | 2 + .../PurePhone/services/evtmgr/CMakeLists.txt | 2 +- .../backlight-handler/BacklightHandler.cpp | 28 +++- .../backlight-handler/BacklightHandler.hpp | 67 --------- .../include/evtmgr/BacklightHandler.hpp | 17 +-- .../ScreenLightControl.cpp | 60 ++++---- .../ScreenLightControl.hpp | 70 +++++++++ 34 files changed, 655 insertions(+), 306 deletions(-) delete mode 100644 products/BellHybrid/services/evtmgr/backlight-handler/BacklightHandler.hpp rename products/BellHybrid/services/evtmgr/include/evtmgr/{ => backlight-handler}/BacklightHandler.hpp (65%) create mode 100644 products/BellHybrid/services/evtmgr/screen-light-control/ScreenLightControl.hpp delete mode 100644 products/PurePhone/services/evtmgr/backlight-handler/BacklightHandler.hpp create mode 100644 products/PurePhone/services/evtmgr/screen-light-control/ScreenLightControl.hpp diff --git a/module-bsp/board/rt1051/bsp/eink_frontlight/eink_frontlight.cpp b/module-bsp/board/rt1051/bsp/eink_frontlight/eink_frontlight.cpp index 8dc830a5605028ff5b9fd7e42c3224d6eabb1556..50aba266b9a5f400e27875e17a1d27b6e0ad4b03 100644 --- a/module-bsp/board/rt1051/bsp/eink_frontlight/eink_frontlight.cpp +++ b/module-bsp/board/rt1051/bsp/eink_frontlight/eink_frontlight.cpp @@ -42,7 +42,9 @@ namespace bsp::eink_frontlight void setBrightness(BrightnessPercentage brightness) { - pwm->SetDutyCycle(gammaCorrection(brightness)); + if (pwm) { + pwm->SetDutyCycle(gammaCorrection(brightness)); + } } void turnOn() diff --git a/module-db/Interface/EventRecord.cpp b/module-db/Interface/EventRecord.cpp index 93c58690b3aeaf9a993d3ed282564c0dc18cac58..8e33aa064fd6b195895901e896134288c6d3424c 100644 --- a/module-db/Interface/EventRecord.cpp +++ b/module-db/Interface/EventRecord.cpp @@ -93,3 +93,8 @@ bool EventRecord::isValid() const { return (EventInfo::isValid() && Record::isValid()); } + +auto SingleEventRecord::isValid() const -> bool +{ + return EventInfo::isValid(); +} diff --git a/module-db/Interface/EventRecord.hpp b/module-db/Interface/EventRecord.hpp index 56e3e2663d34659ef9d5fda53602b728fc49eae5..511726b93b21f6facb26b0edb6034f9c9932fd56 100644 --- a/module-db/Interface/EventRecord.hpp +++ b/module-db/Interface/EventRecord.hpp @@ -65,4 +65,6 @@ struct SingleEventRecord : public Record, public EventInfo SingleEventRecord() = default; SingleEventRecord(std::shared_ptr parent, TimePoint startDate, TimePoint endDate) : EventInfo{parent->name, startDate, endDate, parent->duration, parent->isAllDay}, parent{parent} {}; + + auto isValid() const -> bool; }; diff --git a/module-services/service-evtmgr/backlight-handler/BacklightHandlerCommon.cpp b/module-services/service-evtmgr/backlight-handler/BacklightHandlerCommon.cpp index 293d256868c87f29769ab1f9994ec29dee0ddab1..3af02aad7aa631a16fe25cca5afaff7af74f1f5c 100644 --- a/module-services/service-evtmgr/backlight-handler/BacklightHandlerCommon.cpp +++ b/module-services/service-evtmgr/backlight-handler/BacklightHandlerCommon.cpp @@ -15,17 +15,17 @@ namespace backlight constexpr auto screenLightTimerTimeout = std::chrono::seconds(5); } // namespace timers - HandlerCommon::HandlerCommon(std::shared_ptr settings, sys::Service *parent) - : settings{std::move(settings)}, screenLightControl{std::make_shared( - parent)}, + HandlerCommon::HandlerCommon(std::shared_ptr settings, + std::shared_ptr screenLightController, + sys::Service *parent) + : settings{std::move(settings)}, screenLightController{std::move(screenLightController)}, screenLightTimer{std::make_shared(sys::TimerFactory::createSingleShotTimer( parent, timers::screenLightTimerName, timers::screenLightTimerTimeout, [this](sys::Timer &t) { if (getScreenAutoModeState() == screen_light_control::ScreenLightMode::Automatic && - screenLightControl->isLightOn()) { - screenLightControl->processRequest(screen_light_control::Action::turnOff); + this->screenLightController->isLightOn()) { + this->screenLightController->processRequest(screen_light_control::Action::turnOff); } }))} - {} void HandlerCommon::init() @@ -33,34 +33,24 @@ namespace backlight using namespace screen_light_control; settings->registerValueChange(settings::Brightness::brightnessLevel, [&](const std::string &value) { ManualModeParameters params{utils::getNumericValue(value)}; - screenLightControl->processRequest(Action::setManualModeBrightness, Parameters(params)); + screenLightController->processRequest(Action::setManualModeBrightness, Parameters(params)); }); settings->registerValueChange(settings::Brightness::autoMode, [&]([[maybe_unused]] const std::string &value) { const auto action = getScreenAutoModeState() == ScreenLightMode::Automatic ? Action::enableAutomaticMode : Action::disableAutomaticMode; - screenLightControl->processRequest(action); + screenLightController->processRequest(action); }); settings->registerValueChange(settings::Brightness::state, [&]([[maybe_unused]] const std::string &value) { const auto action = getScreenLightState() ? Action::turnOn : Action::turnOff; if (action == Action::turnOn) { - screenLightTimer->start(); + onScreenLightTurnedOn(); } - screenLightControl->processRequest(action); + screenLightController->processRequest(action); }); } - void HandlerCommon::processScreenRequest(screen_light_control::Action action, - const screen_light_control::Parameters ¶ms) - { - if (action == screen_light_control::Action::enableAutomaticMode) { - startScreenLightTimer(); - } - handleScreenLightSettings(action, params); - screenLightControl->processRequest(action, params); - } - auto HandlerCommon::getValue(const std::string &path) const -> std::string { return settings->getValue(path); @@ -95,8 +85,8 @@ namespace backlight void HandlerCommon::handleScreenLightRefresh() { if (getScreenLightState() && getScreenAutoModeState() == screen_light_control::ScreenLightMode::Automatic) { - if (!screenLightControl->isLightOn()) { - screenLightControl->processRequest(screen_light_control::Action::turnOn); + if (!screenLightController->isLightOn()) { + screenLightController->processRequest(screen_light_control::Action::turnOn); } startScreenLightTimer(); } @@ -119,7 +109,7 @@ namespace backlight break; case screen_light_control::Action::turnOn: setValue(settings::Brightness::state, utils::to_string(true)); - screenLightTimer->start(); + onScreenLightTurnedOn(); break; case screen_light_control::Action::setManualModeBrightness: if (params.hasManualModeParams()) { diff --git a/module-services/service-evtmgr/backlight-handler/BacklightHandlerCommon.hpp b/module-services/service-evtmgr/backlight-handler/BacklightHandlerCommon.hpp index 9c4472056fd14568dce8261649dd4eef4dae52f5..e58143e997d9e91dc7ff2a16c8468d0edec0baeb 100644 --- a/module-services/service-evtmgr/backlight-handler/BacklightHandlerCommon.hpp +++ b/module-services/service-evtmgr/backlight-handler/BacklightHandlerCommon.hpp @@ -19,7 +19,9 @@ namespace backlight class HandlerCommon { public: - HandlerCommon(std::shared_ptr settings, sys::Service *parent); + HandlerCommon(std::shared_ptr settings, + std::shared_ptr screenLightController, + sys::Service *parent); /// initialise in InitHandler when Service is ready void init(); @@ -27,24 +29,27 @@ namespace backlight /// Process request of the screen light control /// @screen_light_control::Action an action to perform /// @screen_light_control::Parameters parameters being set - void processScreenRequest(screen_light_control::Action action, const screen_light_control::Parameters ¶ms); + virtual void processScreenRequest(screen_light_control::Action action, + const screen_light_control::Parameters ¶ms) = 0; [[nodiscard]] auto getScreenLightState() const noexcept -> bool; [[nodiscard]] auto getScreenAutoModeState() const noexcept -> screen_light_control::ScreenLightMode; [[nodiscard]] auto getScreenBrightnessValue() const noexcept -> bsp::eink_frontlight::BrightnessPercentage; private: + virtual void onScreenLightTurnedOn() = 0; + std::shared_ptr settings; - std::shared_ptr screenLightControl; + std::shared_ptr screenLightController; public: auto getScreenLightTimer() noexcept -> std::shared_ptr { return screenLightTimer; } - auto getScreenLightControl() noexcept -> std::shared_ptr + auto getScreenLightControl() noexcept -> std::shared_ptr { - return screenLightControl; + return screenLightController; } void handleScreenLightSettings(screen_light_control::Action action, const screen_light_control::Parameters ¶ms); diff --git a/module-services/service-evtmgr/screen-light-control/ControlFunctions.cpp b/module-services/service-evtmgr/screen-light-control/ControlFunctions.cpp index d8a04970ca53204f6695a90a2f4fcb172cda7cd7..3ea448c271136c8003187410062fc765ed23b0b4 100644 --- a/module-services/service-evtmgr/screen-light-control/ControlFunctions.cpp +++ b/module-services/service-evtmgr/screen-light-control/ControlFunctions.cpp @@ -95,9 +95,23 @@ namespace screen_light_control::functions } } + void setRampState(float state) + { + rampState = state; + } + void setRampTarget(bsp::eink_frontlight::BrightnessPercentage value) { rampTarget = value; } + bool isRampTargetReached() + { + return rampTargetReached; + } + + bsp::eink_frontlight::BrightnessPercentage getRampState() + { + return rampState; + } } // namespace screen_light_control::functions diff --git a/module-services/service-evtmgr/screen-light-control/ControlFunctions.hpp b/module-services/service-evtmgr/screen-light-control/ControlFunctions.hpp index c0a28de04469b77e872ce6e089960c7ceffe05a4..5d192c590b2100643c771ff54efe837936d47d14 100644 --- a/module-services/service-evtmgr/screen-light-control/ControlFunctions.hpp +++ b/module-services/service-evtmgr/screen-light-control/ControlFunctions.hpp @@ -5,6 +5,8 @@ #include #include + +#include #include #include @@ -13,10 +15,18 @@ namespace screen_light_control::functions using BrightnessFunction = std::vector>; + struct LinearProgressFunction + { + float target = 100.0f; + std::chrono::milliseconds duration = std::chrono::milliseconds::zero(); + }; + bsp::eink_frontlight::BrightnessPercentage brightnessRampOut(); void calculateBrightness(bsp::light_sensor::IlluminanceLux measurement); + void setRampState(float state); + void setRampStep(float step); void setHysteresis(float hyst); @@ -25,4 +35,7 @@ namespace screen_light_control::functions void setRampTarget(bsp::eink_frontlight::BrightnessPercentage value); + bool isRampTargetReached(); + + bsp::eink_frontlight::BrightnessPercentage getRampState(); } // namespace screen_light_control::functions diff --git a/module-services/service-evtmgr/screen-light-control/ScreenLightControl.hpp b/module-services/service-evtmgr/screen-light-control/ScreenLightControl.hpp index 1dd45805b2ec85d2e0dbc1f879aba55fdd55078c..9c3a16015dbba81434a095e27f5aa869df55749e 100644 --- a/module-services/service-evtmgr/screen-light-control/ScreenLightControl.hpp +++ b/module-services/service-evtmgr/screen-light-control/ScreenLightControl.hpp @@ -20,46 +20,16 @@ namespace sys /// Processing of ambient light sensor input to screen brightness output. namespace screen_light_control { - /// Control screen light and keeps it's current state - class ScreenLightControl + class ScreenLightController { public: - explicit ScreenLightControl(sys::Service *parent); - ~ScreenLightControl(); - - void processRequest(Action action); - void processRequest(Action action, const Parameters ¶ms); - - [[nodiscard]] auto isLightOn() const noexcept -> bool; - [[nodiscard]] auto getAutoModeState() const noexcept -> ScreenLightMode; - [[nodiscard]] auto getBrightnessValue() const noexcept -> bsp::eink_frontlight::BrightnessPercentage; - - private: - void controlTimerCallback(); - void readoutTimerCallback(); - - void enableTimers(); - void disableTimers(); - - void setParameters(const AutomaticModeParameters ¶ms); - void setParameters(ManualModeParameters params); - void setManualBrightnessLevel(); - - void turnOff(); - void turnOn(); - - void enableAutomaticMode(); - void disableAutomaticMode(); - - static constexpr inline auto CONTROL_TIMER_MS = 25; - static constexpr inline auto READOUT_TIMER_MS = 500; - - sys::TimerHandle controlTimer; - sys::TimerHandle readoutTimer; - - bool lightOn = false; - screen_light_control::ScreenLightMode automaticMode = ScreenLightMode::Manual; - bsp::eink_frontlight::BrightnessPercentage brightnessValue = 0.0; + virtual ~ScreenLightController() noexcept = default; + + virtual void processRequest(Action action) = 0; + virtual void processRequest(Action action, const Parameters ¶ms) = 0; + [[nodiscard]] virtual auto isLightOn() const noexcept -> bool = 0; + [[nodiscard]] virtual auto isAutoModeOn() const noexcept -> bool = 0; + [[nodiscard]] virtual auto getBrightnessValue() const noexcept + -> bsp::eink_frontlight::BrightnessPercentage = 0; }; - } // namespace screen_light_control diff --git a/module-services/service-evtmgr/screen-light-control/ScreenLightControlParameters.cpp b/module-services/service-evtmgr/screen-light-control/ScreenLightControlParameters.cpp index 5611c0927a559e8918c642ec83fc3ab6c9e378a9..d0ae1f17c2f5a4fc05f9bf39a0b42e6d76e1f3ba 100644 --- a/module-services/service-evtmgr/screen-light-control/ScreenLightControlParameters.cpp +++ b/module-services/service-evtmgr/screen-light-control/ScreenLightControlParameters.cpp @@ -18,4 +18,10 @@ namespace screen_light_control Expects(hasManualModeParams()); return manualModeParams.value(); } + + auto Parameters::getLinearProgressModeParams() const noexcept -> const LinearProgressModeParameters & + { + Expects(hasLinearProgressModeParams()); + return linearProgressModeParams.value(); + } } // namespace screen_light_control diff --git a/module-services/service-evtmgr/screen-light-control/ScreenLightControlParameters.hpp b/module-services/service-evtmgr/screen-light-control/ScreenLightControlParameters.hpp index c6d5724bb6820c802ceddec103c8bb819b31dd72..ecadd82ba67dd3b34fed7bc24bb591e3cbfff030 100644 --- a/module-services/service-evtmgr/screen-light-control/ScreenLightControlParameters.hpp +++ b/module-services/service-evtmgr/screen-light-control/ScreenLightControlParameters.hpp @@ -47,18 +47,35 @@ namespace screen_light_control float gammaFactor = 2.5f; }; + struct LinearProgressModeParameters + { + using LinearFunctions = std::vector; + + /// Manually set starting value of the brightness + float startBrightnessValue = 0.0f; + /// Vector of linear functions of progressive screen brightness + LinearFunctions functions{ + functions::LinearProgressFunction{.target = 100.0f, .duration = std::chrono::milliseconds{1500}}}; + /// Hysteresis value of screen brightness control + float brightnessHysteresis = 0.0f; + }; + class Parameters { std::optional manualModeParams; std::optional autoModeParams; + std::optional linearProgressModeParams; public: Parameters() = default; - explicit Parameters(ManualModeParameters manualModeParams) - : manualModeParams{std::make_optional(manualModeParams)} + explicit Parameters(ManualModeParameters manualModeParams) : manualModeParams{manualModeParams} + {} + + explicit Parameters(const AutomaticModeParameters &autoModeParams) : autoModeParams{autoModeParams} {} - explicit Parameters(const AutomaticModeParameters &autoModeParams) - : autoModeParams{std::make_optional(autoModeParams)} + + explicit Parameters(const LinearProgressModeParameters &autoModeParams) + : linearProgressModeParams{autoModeParams} {} [[nodiscard]] bool hasManualModeParams() const noexcept @@ -74,5 +91,12 @@ namespace screen_light_control } [[nodiscard]] auto getAutoModeParams() const noexcept -> const AutomaticModeParameters &; + + [[nodiscard]] bool hasLinearProgressModeParams() const noexcept + { + return linearProgressModeParams.has_value(); + } + + [[nodiscard]] auto getLinearProgressModeParams() const noexcept -> const LinearProgressModeParameters &; }; } // namespace screen_light_control diff --git a/module-services/service-evtmgr/service-evtmgr/ScreenLightControlMessage.hpp b/module-services/service-evtmgr/service-evtmgr/ScreenLightControlMessage.hpp index 57bb3c87e197dd75457c219c9fcaa37a1fd898ac..a9d68939fcc1fb2386a7f1383664eb37b9acf2d3 100644 --- a/module-services/service-evtmgr/service-evtmgr/ScreenLightControlMessage.hpp +++ b/module-services/service-evtmgr/service-evtmgr/ScreenLightControlMessage.hpp @@ -14,16 +14,23 @@ namespace sevm class ScreenLightControlMessage : public sys::DataMessage { const screen_light_control::Action action; + std::optional params; public: - explicit ScreenLightControlMessage(screen_light_control::Action act) - : sys::DataMessage(MessageType::ScreenLightControlAction), action(act) + explicit ScreenLightControlMessage(screen_light_control::Action act, + std::optional params = std::nullopt) + : sys::DataMessage(MessageType::ScreenLightControlAction), action(act), params{std::move(params)} {} [[nodiscard]] auto getAction() const noexcept -> screen_light_control::Action { return action; } + + [[nodiscard]] auto getParams() const noexcept -> const std::optional & + { + return params; + } }; class ScreenLightSetAutoModeParams : public ScreenLightControlMessage @@ -42,6 +49,22 @@ namespace sevm } }; + class ScreenLightSetAutoProgressiveModeParams : public ScreenLightControlMessage + { + screen_light_control::LinearProgressModeParameters params; + + public: + explicit ScreenLightSetAutoProgressiveModeParams(screen_light_control::LinearProgressModeParameters params) + : ScreenLightControlMessage(screen_light_control::Action::setAutomaticModeParameters), params{std::move( + params)} + {} + + [[nodiscard]] auto getParams() const noexcept -> const screen_light_control::LinearProgressModeParameters & + { + return params; + } + }; + class ScreenLightSetManualModeParams : public ScreenLightControlMessage { screen_light_control::ManualModeParameters params; diff --git a/module-services/service-time/AlarmOperations.cpp b/module-services/service-time/AlarmOperations.cpp index d19090e0216203c6df9ff16adba3c300547d303f..058007fd18396c432d2058a439b2e5c3ac922f32 100644 --- a/module-services/service-time/AlarmOperations.cpp +++ b/module-services/service-time/AlarmOperations.cpp @@ -350,10 +350,15 @@ namespace alarms } else { handler->handleOff(*event); + onAlarmTurnedOff(event, alarmType); } } } + void AlarmOperationsCommon::onAlarmTurnedOff(const std::shared_ptr &event, + alarms::AlarmType alarmType) + {} + auto AlarmOperationsCommon::processNextEventsQueue(const TimePoint now) -> void { if (nextSingleEvents.front()->startDate <= now) { diff --git a/module-services/service-time/AlarmOperations.hpp b/module-services/service-time/AlarmOperations.hpp index 9c955d40a3c96edaa487e90bf7e9de443b4c7a73..35529b74174228503a0d9267ce723985545b0a88 100644 --- a/module-services/service-time/AlarmOperations.hpp +++ b/module-services/service-time/AlarmOperations.hpp @@ -153,6 +153,7 @@ namespace alarms void processEvents(TimePoint now); void processNextEventsQueue(const TimePoint now); void processSnoozedEventsQueue(const TimePoint now); + virtual void onAlarmTurnedOff(const std::shared_ptr &event, alarms::AlarmType alarmType); TimePoint getCurrentTime(); void handleSnoozedAlarmsCountChange(); diff --git a/products/BellHybrid/alarms/BellAlarmHandler.cpp b/products/BellHybrid/alarms/BellAlarmHandler.cpp index 070f815a00c9f4f2711ee91f0bc672f42c3dd6c5..8bc2ac0f833dd93fbc2088b2ca67867fc47bd129 100644 --- a/products/BellHybrid/alarms/BellAlarmHandler.cpp +++ b/products/BellHybrid/alarms/BellAlarmHandler.cpp @@ -40,7 +40,7 @@ namespace alarms Actions actions; actions.emplace_back(std::make_unique(*service)); actions.emplace_back(std::make_unique(*service)); - actions.emplace_back(std::make_unique(*service)); + actions.emplace_back(std::make_unique(*service, FrontlightAction::Mode::Manual)); return actions; } @@ -54,6 +54,17 @@ namespace alarms return actions; } + PreWakeUpFrontlightHandler::PreWakeUpFrontlightHandler(sys::Service *service) + : BellAlarmHandler(getActions(service)) + {} + + auto PreWakeUpFrontlightHandler::getActions(sys::Service *service) -> Actions + { + Actions actions; + actions.emplace_back(std::make_unique(*service, FrontlightAction::Mode::LinearProgress)); + return actions; + } + SnoozeChimeHandler::SnoozeChimeHandler(sys::Service *service) : BellAlarmHandler{getActions(service)} {} diff --git a/products/BellHybrid/alarms/CMakeLists.txt b/products/BellHybrid/alarms/CMakeLists.txt index 90dbc7eba5c2841dbfc4ab613e51555a08e4ab7f..41b542170a955356be2e4c96142eddcc8bfb9f7b 100644 --- a/products/BellHybrid/alarms/CMakeLists.txt +++ b/products/BellHybrid/alarms/CMakeLists.txt @@ -38,6 +38,7 @@ target_link_libraries(alarms bell::db bell::appmgr bell::app-common + bell::evtmgr apps-common PUBLIC module-db diff --git a/products/BellHybrid/alarms/include/BellAlarmHandler.hpp b/products/BellHybrid/alarms/include/BellAlarmHandler.hpp index 6c6519380fd70a929a3fcb4194ff6a4f963a6de2..732ac88113034b04694ccb80cee95ca9ed749f9e 100644 --- a/products/BellHybrid/alarms/include/BellAlarmHandler.hpp +++ b/products/BellHybrid/alarms/include/BellAlarmHandler.hpp @@ -41,6 +41,15 @@ namespace alarms static auto getActions(sys::Service *service) -> Actions; }; + class PreWakeUpFrontlightHandler : public BellAlarmHandler + { + public: + explicit PreWakeUpFrontlightHandler(sys::Service *service); + + private: + static auto getActions(sys::Service *service) -> Actions; + }; + class SnoozeChimeHandler : public BellAlarmHandler { public: diff --git a/products/BellHybrid/alarms/src/actions/FrontlightAction.cpp b/products/BellHybrid/alarms/src/actions/FrontlightAction.cpp index ca11e882981588a2b906a7dea994eaf032a01181..dd6a86f4359ce87da6e82b713ea3003cf044d5d5 100644 --- a/products/BellHybrid/alarms/src/actions/FrontlightAction.cpp +++ b/products/BellHybrid/alarms/src/actions/FrontlightAction.cpp @@ -3,22 +3,134 @@ #include "FrontlightAction.hpp" -#include #include +#include + +#include +#include +#include namespace alarms { - FrontlightAction::FrontlightAction(sys::Service &service) : service{service} + namespace + { + class ManualFrontlightAction : public AbstractAlarmAction + { + public: + explicit ManualFrontlightAction(sys::Service &service); + bool execute() override; + bool turnOff() override; + + private: + screen_light_control::ManualModeParameters prepareParameters(); + + sys::Service &service; + }; + + class LinearProgressFrontlightAction : public AbstractAlarmAction + { + public: + explicit LinearProgressFrontlightAction(sys::Service &service); + bool execute() override; + bool turnOff() override; + + private: + screen_light_control::LinearProgressModeParameters prepareParameters(); + + sys::Service &service; + settings::Settings settings; + }; + + std::unique_ptr createFrontlightImplementation(sys::Service &service, + FrontlightAction::Mode mode) + { + switch (mode) { + case FrontlightAction::Mode::Manual: + return std::make_unique(service); + case FrontlightAction::Mode::LinearProgress: + return std::make_unique(service); + } + return nullptr; + } + } // namespace + + FrontlightAction::FrontlightAction(sys::Service &service, Mode mode) + : pimpl{createFrontlightImplementation(service, mode)} {} bool FrontlightAction::execute() { + return pimpl->execute(); + } + + bool FrontlightAction::turnOff() + { + return pimpl->turnOff(); + } + + ManualFrontlightAction::ManualFrontlightAction(sys::Service &service) : service{service} + {} + + bool ManualFrontlightAction::execute() + { + service.bus.sendUnicast( + std::make_shared(screen_light_control::Action::disableAutomaticMode), + service::name::evt_manager); + + auto params = prepareParameters(); + service.bus.sendUnicast(std::make_shared( + screen_light_control::Action::turnOn, screen_light_control::Parameters{params}), + service::name::evt_manager); + return true; + } + + screen_light_control::ManualModeParameters ManualFrontlightAction::prepareParameters() + { + return screen_light_control::ManualModeParameters{.manualModeBrightness = 100.0f}; + } + + bool ManualFrontlightAction::turnOff() + { + service.bus.sendUnicast( + std::make_shared(screen_light_control::Action::turnOff), + service::name::evt_manager); + return true; + } + + LinearProgressFrontlightAction::LinearProgressFrontlightAction(sys::Service &service) : service{service} + { + settings.init(service::ServiceProxy{service.weak_from_this()}); + } + + bool LinearProgressFrontlightAction::execute() + { + const auto params = prepareParameters(); + service.bus.sendUnicast(std::make_shared(params), + service::name::evt_manager); + service.bus.sendUnicast( + std::make_shared(screen_light_control::Action::enableAutomaticMode), + service::name::evt_manager); service.bus.sendUnicast(std::make_shared(screen_light_control::Action::turnOn), service::name::evt_manager); return true; } - bool FrontlightAction::turnOff() + screen_light_control::LinearProgressModeParameters LinearProgressFrontlightAction::prepareParameters() + { + constexpr auto firstTargetDuration = std::chrono::seconds{5}; + const auto value = settings.getValue(bell::settings::PrewakeUp::lightDuration, settings::SettingsScope::Global); + const auto lightDuration = std::chrono::minutes{utils::toNumeric(value)}; + const auto secondTargetDuration = lightDuration - std::chrono::minutes{1} - firstTargetDuration; + return screen_light_control::LinearProgressModeParameters{ + .startBrightnessValue = 0.0f, + .functions = {screen_light_control::functions::LinearProgressFunction{.target = 10.0f, + .duration = firstTargetDuration}, + screen_light_control::functions::LinearProgressFunction{.target = 100.0f, + .duration = secondTargetDuration}}, + .brightnessHysteresis = 0.0f}; + } + + bool LinearProgressFrontlightAction::turnOff() { service.bus.sendUnicast( std::make_shared(screen_light_control::Action::turnOff), diff --git a/products/BellHybrid/alarms/src/actions/FrontlightAction.hpp b/products/BellHybrid/alarms/src/actions/FrontlightAction.hpp index 9251e36454436e1a5187fee30456f63d5baa7f77..34b28320694247f0953f5b2024918343c4b009f3 100644 --- a/products/BellHybrid/alarms/src/actions/FrontlightAction.hpp +++ b/products/BellHybrid/alarms/src/actions/FrontlightAction.hpp @@ -12,12 +12,17 @@ namespace alarms class FrontlightAction : public AbstractAlarmAction { public: - explicit FrontlightAction(sys::Service &service); + enum class Mode + { + Manual, + LinearProgress + }; + + FrontlightAction(sys::Service &service, Mode mode); bool execute() override; bool turnOff() override; private: - sys::Service &service; + std::unique_ptr pimpl; }; - } // namespace alarms diff --git a/products/BellHybrid/services/evtmgr/CMakeLists.txt b/products/BellHybrid/services/evtmgr/CMakeLists.txt index 8c3b6a8b8e55560a8648ce926b7f492f606cb9d9..ea318057f2104146bdd10813767bf263e68a0e9b 100644 --- a/products/BellHybrid/services/evtmgr/CMakeLists.txt +++ b/products/BellHybrid/services/evtmgr/CMakeLists.txt @@ -24,6 +24,7 @@ target_sources(evtmgr PUBLIC include/evtmgr/EventManager.hpp include/evtmgr/api/TemperatureApi.hpp + include/evtmgr/backlight-handler/BacklightHandler.hpp ) target_include_directories(evtmgr diff --git a/products/BellHybrid/services/evtmgr/EventManager.cpp b/products/BellHybrid/services/evtmgr/EventManager.cpp index d08aeac1bf5151471172eac210490a75c373e152..2c8839867339ed31d995bf6381dcc120798a7329 100644 --- a/products/BellHybrid/services/evtmgr/EventManager.cpp +++ b/products/BellHybrid/services/evtmgr/EventManager.cpp @@ -71,7 +71,8 @@ void EventManager::initProductEvents() connect(typeid(sevm::ScreenLightControlMessage), [&](sys::Message *msgl) { auto *m = static_cast(msgl); - backlightHandler.processScreenRequest(m->getAction(), screen_light_control::Parameters()); + const auto params = m->getParams(); + backlightHandler.processScreenRequest(m->getAction(), params.value_or(screen_light_control::Parameters())); return sys::msgHandled(); }); @@ -81,6 +82,12 @@ void EventManager::initProductEvents() return sys::msgHandled(); }); + connect(typeid(sevm::ScreenLightSetAutoProgressiveModeParams), [&](sys::Message *msgl) { + auto *m = static_cast(msgl); + backlightHandler.processScreenRequest(m->getAction(), screen_light_control::Parameters(m->getParams())); + return sys::msgHandled(); + }); + connect(typeid(sevm::ScreenLightSetManualModeParams), [&](sys::Message *msgl) { auto *m = static_cast(msgl); backlightHandler.processScreenRequest(m->getAction(), screen_light_control::Parameters(m->getParams())); @@ -93,9 +100,6 @@ void EventManager::initProductEvents() backlightHandler.getScreenLightState(), backlightHandler.getScreenAutoModeState(), params); return msg; }); - - backlightHandler.processScreenRequest(screen_light_control::Action::enableAutomaticMode, - screen_light_control::Parameters()); } sys::MessagePointer EventManager::DataReceivedHandler(sys::DataMessage *msgl, sys::ResponseMessage *resp) diff --git a/products/BellHybrid/services/evtmgr/backlight-handler/BacklightHandler.cpp b/products/BellHybrid/services/evtmgr/backlight-handler/BacklightHandler.cpp index a272ea02050b784a0fcf6ef87b696d1ccc5580ec..75fde7b93230f0a755927d7d1431976a2492c872 100644 --- a/products/BellHybrid/services/evtmgr/backlight-handler/BacklightHandler.cpp +++ b/products/BellHybrid/services/evtmgr/backlight-handler/BacklightHandler.cpp @@ -1,11 +1,13 @@ // Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved. // For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md -#include -#include +#include + +#include + #include + #include -#include #include namespace backlight @@ -17,29 +19,45 @@ namespace backlight } // namespace timers Handler::Handler(std::shared_ptr settings, sys::Service *parent) - : HandlerCommon(settings, parent), screenLightControl{getScreenLightControl()}, screenLightTimer{ - getScreenLightTimer()} + : HandlerCommon( + std::move(settings), std::make_shared(parent), parent) {} - void Handler::handleKeyPressed([[maybe_unused]] const int key) + void Handler::handleKeyPressed([[maybe_unused]] int key) { handleScreenLightRefresh(key); } - void Handler::handleScreenLightRefresh([[maybe_unused]] const int key) + void Handler::handleScreenLightRefresh([[maybe_unused]] int key) { - if (getScreenAutoModeState() == screen_light_control::ScreenLightMode::Automatic) { - if (!screenLightControl->isLightOn() && (key == static_cast(KeyMap::Frontlight))) { - screenLightControl->processRequest(screen_light_control::Action::turnOn); - screenLightTimer->restart(timers::screenLightTimerTimeout); - } - else if (screenLightControl->isLightOn() && (key != static_cast(KeyMap::Frontlight))) { - screenLightTimer->restart(timers::screenLightTimerHoldTimeout); + auto controller = getScreenLightControl(); + auto timer = getScreenLightTimer(); + if (!controller->isLightOn() && (key == static_cast(KeyMap::Frontlight))) { + controller->processRequest(screen_light_control::Action::turnOn); + timer->restart(timers::screenLightTimerTimeout); + } + else if (controller->isLightOn()) { + if (controller->isAutoModeOn() || key == static_cast(KeyMap::Frontlight)) { + controller->processRequest(screen_light_control::Action::turnOff); + timer->stop(); } - else if (key == static_cast(KeyMap::Frontlight)) { - screenLightControl->processRequest(screen_light_control::Action::turnOff); - screenLightTimer->stop(); + else { + timer->restart(timers::screenLightTimerHoldTimeout); } } } + + void Handler::processScreenRequest(screen_light_control::Action action, + const screen_light_control::Parameters ¶ms) + { + handleScreenLightSettings(action, params); + getScreenLightControl()->processRequest(action, params); + } + + void Handler::onScreenLightTurnedOn() + { + if (!getScreenLightControl()->isAutoModeOn()) { + startScreenLightTimer(); + } + } } // namespace backlight diff --git a/products/BellHybrid/services/evtmgr/backlight-handler/BacklightHandler.hpp b/products/BellHybrid/services/evtmgr/backlight-handler/BacklightHandler.hpp deleted file mode 100644 index c3aef24da2baf57663846a5df0a508f879fb13c0..0000000000000000000000000000000000000000 --- a/products/BellHybrid/services/evtmgr/backlight-handler/BacklightHandler.hpp +++ /dev/null @@ -1,37 +0,0 @@ -// 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 -#include -#include -#include -#include - -namespace settings -{ - class Settings; -} // namespace settings - -namespace backlight -{ - /// @brief Backlight events handler - class HandlerBell : public Handler - { - public: - HandlerBell(std::shared_ptr settings, sys::Service *parent); - - void handleKeyPressed(const int key = 0); - - private: - std::shared_ptr settings; - std::unique_ptr screenLightControl; - /// Timer that keeps screen backlight on for a certain time if there was key pressed - sys::TimerHandle screenLightTimer; - void startScreenLightTimer(); - void handleScreenLightRefresh(const int key = 0); - void handleScreenLightSettings(screen_light_control::Action action, - const screen_light_control::Parameters ¶ms); - }; -} // namespace backlight diff --git a/products/BellHybrid/services/evtmgr/include/evtmgr/EventManager.hpp b/products/BellHybrid/services/evtmgr/include/evtmgr/EventManager.hpp index 8256bc1bac76a6e061342014be436a0f88dcd5cb..1436a96bf27045a3275f6e90f4c74d59292b23c3 100644 --- a/products/BellHybrid/services/evtmgr/include/evtmgr/EventManager.hpp +++ b/products/BellHybrid/services/evtmgr/include/evtmgr/EventManager.hpp @@ -5,7 +5,7 @@ #include -#include "BacklightHandler.hpp" +#include "backlight-handler/BacklightHandler.hpp" class KeySequenceMgr; diff --git a/products/BellHybrid/services/evtmgr/include/evtmgr/BacklightHandler.hpp b/products/BellHybrid/services/evtmgr/include/evtmgr/backlight-handler/BacklightHandler.hpp similarity index 65% rename from products/BellHybrid/services/evtmgr/include/evtmgr/BacklightHandler.hpp rename to products/BellHybrid/services/evtmgr/include/evtmgr/backlight-handler/BacklightHandler.hpp index 03a78d0ad8b74b57437988c3246980baed2f476d..4b13f7327b5e70211e2517aee24d43d934b0618f 100644 --- a/products/BellHybrid/services/evtmgr/include/evtmgr/BacklightHandler.hpp +++ b/products/BellHybrid/services/evtmgr/include/evtmgr/backlight-handler/BacklightHandler.hpp @@ -22,12 +22,14 @@ namespace backlight public: Handler(std::shared_ptr settings, sys::Service *parent); - void handleKeyPressed([[maybe_unused]] const int key = 0); + void handleKeyPressed(int key = 0); + + void processScreenRequest(screen_light_control::Action action, + const screen_light_control::Parameters ¶ms) override; private: - std::shared_ptr screenLightControl; - /// Timer that keeps screen backlight on for a certain time if there was key pressed - std::shared_ptr screenLightTimer; - void handleScreenLightRefresh([[maybe_unused]] const int key = 0); + void handleScreenLightRefresh(int key = 0); + + void onScreenLightTurnedOn() override; }; } // namespace backlight diff --git a/products/BellHybrid/services/evtmgr/screen-light-control/ScreenLightControl.cpp b/products/BellHybrid/services/evtmgr/screen-light-control/ScreenLightControl.cpp index 3ea64e233d0690e4e584980455d1f3646cb2cf23..632dface92397202a7fdf907c6b96516531e500b 100644 --- a/products/BellHybrid/services/evtmgr/screen-light-control/ScreenLightControl.cpp +++ b/products/BellHybrid/services/evtmgr/screen-light-control/ScreenLightControl.cpp @@ -1,44 +1,42 @@ // Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved. // For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md -#include -#include -#include +#include "ScreenLightControl.hpp" + #include +#include -namespace screen_light_control +namespace bell::screen_light_control { - ScreenLightControl::ScreenLightControl(sys::Service *parent) + ScreenLightController::ScreenLightController(sys::Service *parent) { controlTimer = sys::TimerFactory::createPeriodicTimer(parent, "LightControlTimer", std::chrono::milliseconds{CONTROL_TIMER_MS}, [this](sys::Timer &) { controlTimerCallback(); }); - readoutTimer = sys::TimerFactory::createPeriodicTimer(parent, - "LightSensorReadoutTimer", - std::chrono::milliseconds{READOUT_TIMER_MS}, - [this](sys::Timer &) { readoutTimerCallback(); }); - setParameters(screen_light_control::AutomaticModeParameters()); + setParameters(ManualModeParameters{}); } - ScreenLightControl::~ScreenLightControl() + ScreenLightController::~ScreenLightController() { disableTimers(); } - void ScreenLightControl::processRequest(Action action) + void ScreenLightController::processRequest(Action action) { - processRequest(action, Parameters()); + processRequest(action, Parameters{}); } - void ScreenLightControl::processRequest(Action action, const Parameters ¶ms) + + void ScreenLightController::processRequest(Action action, const Parameters ¶ms) { switch (action) { case Action::turnOff: turnOff(); break; case Action::turnOn: - turnOn(); + turnOn(params.hasManualModeParams() ? std::optional(params.getManualModeParams()) + : std::nullopt); break; case Action::enableAutomaticMode: enableAutomaticMode(); @@ -52,73 +50,106 @@ namespace screen_light_control } break; case Action::setAutomaticModeParameters: - if (params.hasAutoModeParams()) { - setParameters(params.getAutoModeParams()); + if (params.hasLinearProgressModeParams()) { + setParameters(params.getLinearProgressModeParams()); } break; } } - void ScreenLightControl::controlTimerCallback() + void ScreenLightController::controlTimerCallback() { - bsp::eink_frontlight::setBrightness(functions::brightnessRampOut()); - } + auto currentBrightness = ::screen_light_control::functions::brightnessRampOut(); - void ScreenLightControl::readoutTimerCallback() - { - // functions::calculateBrightness(brightnessValue); + bsp::eink_frontlight::setBrightness(currentBrightness); + if (::screen_light_control::functions::isRampTargetReached()) { + if (!automaticModeFunctions.empty()) { + setUpAutomaticFunction(getNextAutomaticFunction(), currentBrightness); + } + else { + disableAutomaticMode(); + } + } } - auto ScreenLightControl::getAutoModeState() const noexcept -> ScreenLightMode + auto ScreenLightController::isLightOn() const noexcept -> bool { - return automaticMode; + return lightOn; } - auto ScreenLightControl::isLightOn() const noexcept -> bool + bool ScreenLightController::isAutoModeOn() const noexcept { - return lightOn; + return automaticMode == ScreenLightMode::Automatic; } - auto ScreenLightControl::getBrightnessValue() const noexcept -> bsp::eink_frontlight::BrightnessPercentage + auto ScreenLightController::getBrightnessValue() const noexcept -> bsp::eink_frontlight::BrightnessPercentage { return brightnessValue; } - void ScreenLightControl::enableTimers() + void ScreenLightController::enableTimers() { controlTimer.start(); - readoutTimer.start(); } - void ScreenLightControl::disableTimers() + void ScreenLightController::disableTimers() { controlTimer.stop(); - readoutTimer.stop(); } - void ScreenLightControl::setParameters(const AutomaticModeParameters ¶ms) + void ScreenLightController::setParameters(const LinearProgressModeParameters ¶ms) { + if (params.functions.empty()) { + LOG_ERROR("Functions are not defined. Cannot proceed with automatic mode."); + disableTimers(); + return; + } + setAutomaticModeFunctions(params.functions); + if (lightOn && automaticMode == ScreenLightMode::Automatic) { disableTimers(); } - functions::setRampStep(100.0f * (static_cast(CONTROL_TIMER_MS) / static_cast(params.rampTimeMS))); - functions::setHysteresis(params.brightnessHysteresis); - functions::setFunctionFromPoints(params.functionPoints); + ::screen_light_control::functions::setHysteresis(params.brightnessHysteresis); + setUpAutomaticFunction(getNextAutomaticFunction(), ::screen_light_control::functions::getRampState()); + setManualBrightnessLevel(params.startBrightnessValue); if (lightOn && automaticMode == ScreenLightMode::Automatic) { enableTimers(); } } - void ScreenLightControl::setParameters(ManualModeParameters params) + void ScreenLightController::setAutomaticModeFunctions( + const LinearProgressModeParameters::LinearFunctions &functions) + { + automaticModeFunctions = LinearProgressModeParameters::LinearFunctions{functions.rbegin(), functions.rend()}; + } + + ::screen_light_control::functions::LinearProgressFunction ScreenLightController::getNextAutomaticFunction() + { + auto function = automaticModeFunctions.back(); + automaticModeFunctions.pop_back(); + return function; + } + + void ScreenLightController::setUpAutomaticFunction( + ::screen_light_control::functions::LinearProgressFunction function, + bsp::eink_frontlight::BrightnessPercentage currentBrightness) + { + ::screen_light_control::functions::setRampStep( + std::abs(function.target - currentBrightness) / + (static_cast(function.duration.count()) / CONTROL_TIMER_MS)); + ::screen_light_control::functions::setRampTarget(function.target); + } + + void ScreenLightController::setParameters(ManualModeParameters params) { brightnessValue = params.manualModeBrightness; - functions::setRampTarget(brightnessValue); - setManualBrightnessLevel(); + ::screen_light_control::functions::setRampTarget(brightnessValue); + setManualBrightnessLevel(brightnessValue); } - void ScreenLightControl::enableAutomaticMode() + void ScreenLightController::enableAutomaticMode() { if (lightOn) { enableTimers(); @@ -126,15 +157,22 @@ namespace screen_light_control automaticMode = ScreenLightMode::Automatic; } - void ScreenLightControl::disableAutomaticMode() + void ScreenLightController::disableAutomaticMode() { disableTimers(); automaticMode = ScreenLightMode::Manual; - setManualBrightnessLevel(); + automaticModeFunctions.clear(); + setManualBrightnessLevel(brightnessValue); } - void ScreenLightControl::turnOn() + void ScreenLightController::turnOn(const std::optional ¶ms) { + if (params.has_value()) { + const auto brightness = params->manualModeBrightness; + ::screen_light_control::functions::setRampTarget(brightness); + setManualBrightnessLevel(brightness); + } + bsp::eink_frontlight::turnOn(); if (automaticMode == ScreenLightMode::Automatic) { enableTimers(); @@ -142,16 +180,16 @@ namespace screen_light_control lightOn = true; } - void ScreenLightControl::setManualBrightnessLevel() + void ScreenLightController::setManualBrightnessLevel(bsp::eink_frontlight::BrightnessPercentage brightness) { - bsp::eink_frontlight::setBrightness(brightnessValue); + bsp::eink_frontlight::setBrightness(brightness); + ::screen_light_control::functions::setRampState(brightness); } - void ScreenLightControl::turnOff() + void ScreenLightController::turnOff() { bsp::eink_frontlight::turnOff(); - disableTimers(); + disableAutomaticMode(); lightOn = false; } - } // namespace screen_light_control diff --git a/products/BellHybrid/services/evtmgr/screen-light-control/ScreenLightControl.hpp b/products/BellHybrid/services/evtmgr/screen-light-control/ScreenLightControl.hpp new file mode 100644 index 0000000000000000000000000000000000000000..b7fdaa5a5e8ab9325dfa1f472eb5283ee356e391 --- /dev/null +++ b/products/BellHybrid/services/evtmgr/screen-light-control/ScreenLightControl.hpp @@ -0,0 +1,71 @@ +// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved. +// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md + +#pragma once + +#include +#include + +#include + +#include + +namespace sys +{ + class Service; +} // namespace sys + +/// Screen light control algorithm. Automatic/Manual mode of operation. +/// Processing of ambient light sensor input to screen brightness output. +namespace bell::screen_light_control +{ + /// Control screen light and keeps it's current state + class ScreenLightController : public ::screen_light_control::ScreenLightController + { + public: + using Action = ::screen_light_control::Action; + using Parameters = ::screen_light_control::Parameters; + using ScreenLightMode = ::screen_light_control::ScreenLightMode; + using ManualModeParameters = ::screen_light_control::ManualModeParameters; + using LinearProgressModeParameters = ::screen_light_control::LinearProgressModeParameters; + + explicit ScreenLightController(sys::Service *parent); + ~ScreenLightController() override; + + void processRequest(Action action) override; + void processRequest(Action action, const Parameters ¶ms) override; + + [[nodiscard]] auto isLightOn() const noexcept -> bool override; + [[nodiscard]] bool isAutoModeOn() const noexcept override; + [[nodiscard]] auto getBrightnessValue() const noexcept -> bsp::eink_frontlight::BrightnessPercentage override; + + private: + void controlTimerCallback(); + + void enableTimers(); + void disableTimers(); + + void setParameters(const LinearProgressModeParameters ¶ms); + void setParameters(ManualModeParameters params); + void setManualBrightnessLevel(bsp::eink_frontlight::BrightnessPercentage brightness); + + void setAutomaticModeFunctions(const LinearProgressModeParameters::LinearFunctions &functions); + ::screen_light_control::functions::LinearProgressFunction getNextAutomaticFunction(); + void setUpAutomaticFunction(::screen_light_control::functions::LinearProgressFunction function, + bsp::eink_frontlight::BrightnessPercentage currentBrightness); + + void turnOff(); + void turnOn(const std::optional ¶ms = std::nullopt); + + void enableAutomaticMode(); + void disableAutomaticMode(); + + static constexpr inline auto CONTROL_TIMER_MS = 25; + + sys::TimerHandle controlTimer; + bool lightOn = false; + ScreenLightMode automaticMode = ScreenLightMode::Manual; + bsp::eink_frontlight::BrightnessPercentage brightnessValue = 0.0; + LinearProgressModeParameters::LinearFunctions automaticModeFunctions; + }; +} // namespace bell::screen_light_control diff --git a/products/BellHybrid/services/time/AlarmOperations.cpp b/products/BellHybrid/services/time/AlarmOperations.cpp index 64f2e492823e8642d2d10b00a2627f9c09b581ba..3aeb468c2ab2ef00f696c64c7127536ed61cc3cc 100644 --- a/products/BellHybrid/services/time/AlarmOperations.cpp +++ b/products/BellHybrid/services/time/AlarmOperations.cpp @@ -119,6 +119,8 @@ namespace alarms std::make_shared(service)); alarmOperations->addAlarmExecutionHandler(alarms::AlarmType::PreWakeUpChime, std::make_shared(service)); + alarmOperations->addAlarmExecutionHandler(alarms::AlarmType::PreWakeUpFrontlight, + std::make_shared(service)); alarmOperations->addAlarmExecutionHandler(alarms::AlarmType::SnoozeChime, std::make_shared(service)); alarmOperations->addAlarmExecutionHandler(alarms::AlarmType::BedtimeReminder, @@ -157,8 +159,8 @@ namespace alarms return; } - auto nextEvent = *(nextSingleEvents.front()); - if (getAlarmEventType(nextEvent) != alarms::AlarmType::Clock) { + auto nextEvent = getNextPreWakeUpEvent(); + if (!nextEvent.isValid()) { return; } @@ -178,6 +180,23 @@ namespace alarms } } + SingleEventRecord AlarmOperations::getNextPreWakeUpEvent() + { + const auto event = *(nextSingleEvents.front()); + if (getAlarmEventType(event) != alarms::AlarmType::Clock) { + return {}; + } + + auto found = std::find_if(snoozedSingleEvents.begin(), snoozedSingleEvents.end(), [ev = event](auto &event) { + return ev.parent->ID == event->parent->ID; + }); + if (found != snoozedSingleEvents.end()) { + return {}; + } + + return event; + } + void AlarmOperations::handlePreWakeUp(const SingleEventRecord &event, PreWakeUp::Decision decision) { if (auto alarmEventPtr = std::dynamic_pointer_cast(event.parent); alarmEventPtr) { @@ -225,6 +244,17 @@ namespace alarms } } + void AlarmOperations::onAlarmTurnedOff([[maybe_unused]] const std::shared_ptr &event, + alarms::AlarmType alarmType) + { + if (alarmType != alarms::AlarmType::Clock) { + return; + } + + handleAlarmEvent(event, alarms::AlarmType::PreWakeUpChime, false); + handleAlarmEvent(event, alarms::AlarmType::PreWakeUpFrontlight, false); + } + PreWakeUp::PreWakeUp(std::unique_ptr &&settingsProvider) : settingsProvider{std::move(settingsProvider)} {} diff --git a/products/BellHybrid/services/time/include/time/AlarmOperations.hpp b/products/BellHybrid/services/time/include/time/AlarmOperations.hpp index c3e4547a7a0831ba97ad9968692f8a70ab4dde49..c0b148e7a21817fc6446c7e507b8fae77adf5ee7 100644 --- a/products/BellHybrid/services/time/include/time/AlarmOperations.hpp +++ b/products/BellHybrid/services/time/include/time/AlarmOperations.hpp @@ -101,10 +101,12 @@ namespace alarms void stopAllSnoozeChimes(); private: + SingleEventRecord getNextPreWakeUpEvent(); 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 &event, alarms::AlarmType alarmType) override; PreWakeUp preWakeUp; std::unique_ptr snoozeChimeSettings; diff --git a/products/PurePhone/services/evtmgr/CMakeLists.txt b/products/PurePhone/services/evtmgr/CMakeLists.txt index 2d0a9680e2e2d7b65fd03dceef2f423e22dcfdd5..ff8f481945474736de86851d97e8cf1944b609d4 100644 --- a/products/PurePhone/services/evtmgr/CMakeLists.txt +++ b/products/PurePhone/services/evtmgr/CMakeLists.txt @@ -14,7 +14,7 @@ target_sources(evtmgr target_include_directories(evtmgr PRIVATE - $ PUBLIC $ ) diff --git a/products/PurePhone/services/evtmgr/backlight-handler/BacklightHandler.cpp b/products/PurePhone/services/evtmgr/backlight-handler/BacklightHandler.cpp index 8aba962e84064a0322352b00d0c249f8ab753029..895ca83f2701ae4b4391a8b30fcc081364be909b 100644 --- a/products/PurePhone/services/evtmgr/backlight-handler/BacklightHandler.cpp +++ b/products/PurePhone/services/evtmgr/backlight-handler/BacklightHandler.cpp @@ -2,6 +2,8 @@ // For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md #include +#include + #include #include #include @@ -16,21 +18,30 @@ namespace backlight } // namespace timers Handler::Handler(std::shared_ptr settings, sys::Service *parent) - : HandlerCommon(settings, parent), screenLightControl{getScreenLightControl()}, - screenLightTimer{getScreenLightTimer()}, - + : HandlerCommon( + std::move(settings), std::make_shared(parent), parent), keypadLightTimer{sys::TimerFactory::createSingleShotTimer( parent, timers::keypadLightTimerName, timers::keypadLightTimerTimeout, [this](sys::Timer &) { bsp::keypad_backlight::shutdown(); })} {} - void Handler::handleKeyPressed() + void Handler::handleKeyPressed([[maybe_unused]] int key) { handleKeypadLightRefresh(); handleScreenLightRefresh(); } + void Handler::processScreenRequest(screen_light_control::Action action, + const screen_light_control::Parameters ¶ms) + { + if (action == screen_light_control::Action::enableAutomaticMode) { + startScreenLightTimer(); + } + handleScreenLightSettings(action, params); + getScreenLightControl()->processRequest(action, params); + } + void Handler::stopKeypadTimer() { if (keypadLightState == bsp::keypad_backlight::State::activeMode) { @@ -116,10 +127,15 @@ namespace backlight void Handler::handleScreenLightRefresh([[maybe_unused]] const int key) { if (getScreenLightState() && getScreenAutoModeState() == screen_light_control::ScreenLightMode::Automatic) { - if (!screenLightControl->isLightOn()) { - screenLightControl->processRequest(screen_light_control::Action::turnOn); + if (!getScreenLightControl()->isLightOn()) { + getScreenLightControl()->processRequest(screen_light_control::Action::turnOn); } startScreenLightTimer(); } } + + void Handler::onScreenLightTurnedOn() + { + startScreenLightTimer(); + } } // namespace backlight diff --git a/products/PurePhone/services/evtmgr/backlight-handler/BacklightHandler.hpp b/products/PurePhone/services/evtmgr/backlight-handler/BacklightHandler.hpp deleted file mode 100644 index 689726484a4e014e2399c5dffa21ad747af8b6e5..0000000000000000000000000000000000000000 --- a/products/PurePhone/services/evtmgr/backlight-handler/BacklightHandler.hpp +++ /dev/null @@ -1,67 +0,0 @@ -// 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 -#include -#include -#include - -namespace settings -{ - class Settings; -} // namespace settings - -namespace backlight -{ - /// @brief Backlight events handler - class Handler - { - public: - Handler(std::shared_ptr settings, sys::Service *parent); - - /// initialise in InitHandler when Service is ready - void init(); - - /// Process request of the screen light control - /// @screen_light_control::Action an action to perform - /// @screen_light_control::Parameters parameters being set - void processScreenRequest(screen_light_control::Action action, const screen_light_control::Parameters ¶ms); - - void handleKeyPressed(const int key = 0); - /// Process request of the keypad light control - /// @keypad_backlight::action an action to perform - /// @return True if request was processed successfully, false otherwise - auto processKeypadRequest(bsp::keypad_backlight::Action action) -> bool; - - [[nodiscard]] auto getScreenLightState() const noexcept -> bool; - [[nodiscard]] auto getScreenAutoModeState() const noexcept -> screen_light_control::ScreenLightMode; - [[nodiscard]] auto getScreenBrightnessValue() const noexcept -> bsp::eink_frontlight::BrightnessPercentage; - - protected: - [[nodiscard]] auto getValue(const std::string &path) const -> std::string; - void setValue(const std::string &path, const std::string &value); - - private: - std::shared_ptr settings; - std::unique_ptr screenLightControl; - /// Timer that keeps key backlight on for a certain time if there was key pressed - sys::TimerHandle keypadLightTimer; - /// Timer that keeps screen backlight on for a certain time if there was key pressed - sys::TimerHandle screenLightTimer; - bsp::keypad_backlight::State keypadLightState = bsp::keypad_backlight::State::off; - bool isKeypadLightInCallMode = false; - - void startKeypadLightTimer(); - void startScreenLightTimer(); - void stopKeypadTimer(); - void setKeypadLightInCallMode(bool value) noexcept; - void setKeypadLightState(bsp::keypad_backlight::State value) noexcept; - void restoreKeypadLightState(); - void handleKeypadLightRefresh(); - void handleScreenLightRefresh(const int key = 0); - void handleScreenLightSettings(screen_light_control::Action action, - const screen_light_control::Parameters ¶ms); - }; -} // namespace backlight diff --git a/products/PurePhone/services/evtmgr/include/evtmgr/BacklightHandler.hpp b/products/PurePhone/services/evtmgr/include/evtmgr/BacklightHandler.hpp index 7358bd798c1cfb6952edf1d1e501c0a72fdae015..f029d5c84dde53130e96bfdd4ead6edc4bcb5869 100644 --- a/products/PurePhone/services/evtmgr/include/evtmgr/BacklightHandler.hpp +++ b/products/PurePhone/services/evtmgr/include/evtmgr/BacklightHandler.hpp @@ -22,19 +22,21 @@ namespace backlight public: Handler(std::shared_ptr settings, sys::Service *parent); - void handleKeyPressed(); + void handleKeyPressed(int key = 0); /// Process request of the keypad light control /// @keypad_backlight::action an action to perform /// @return True if request was processed successfully, false otherwise auto processKeypadRequest(bsp::keypad_backlight::Action action) -> bool; + void processScreenRequest(screen_light_control::Action action, + const screen_light_control::Parameters ¶ms) override; + private: - std::shared_ptr screenLightControl; - /// Timer that keeps screen backlight on for a certain time if there was key pressed - std::shared_ptr screenLightTimer; + std::shared_ptr settings; /// Timer that keeps key backlight on for a certain time if there was key pressed sys::TimerHandle keypadLightTimer; - + /// Timer that keeps screen backlight on for a certain time if there was key pressed + sys::TimerHandle screenLightTimer; bsp::keypad_backlight::State keypadLightState = bsp::keypad_backlight::State::off; bool isKeypadLightInCallMode = false; @@ -44,8 +46,7 @@ namespace backlight void setKeypadLightState(bsp::keypad_backlight::State value) noexcept; void restoreKeypadLightState(); void handleKeypadLightRefresh(); - void handleScreenLightRefresh([[maybe_unused]] const int key = 0); - void handleScreenLightSettings(screen_light_control::Action action, - const screen_light_control::Parameters ¶ms); + void handleScreenLightRefresh(int key = 0); + void onScreenLightTurnedOn() override; }; } // namespace backlight diff --git a/products/PurePhone/services/evtmgr/screen-light-control/ScreenLightControl.cpp b/products/PurePhone/services/evtmgr/screen-light-control/ScreenLightControl.cpp index 2d3e061e5ce005f2732d7d51819fa9485862916d..952e9885c3d718b6e21b256ddc19b5426ac78d20 100644 --- a/products/PurePhone/services/evtmgr/screen-light-control/ScreenLightControl.cpp +++ b/products/PurePhone/services/evtmgr/screen-light-control/ScreenLightControl.cpp @@ -1,15 +1,15 @@ // Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved. // For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md -#include -#include +#include "ScreenLightControl.hpp" + #include #include -namespace screen_light_control +namespace pure::screen_light_control { - ScreenLightControl::ScreenLightControl(sys::Service *parent) + ScreenLightController::ScreenLightController(sys::Service *parent) { controlTimer = sys::TimerFactory::createPeriodicTimer(parent, "LightControlTimer", @@ -20,19 +20,20 @@ namespace screen_light_control std::chrono::milliseconds{READOUT_TIMER_MS}, [this](sys::Timer &) { readoutTimerCallback(); }); - setParameters(screen_light_control::AutomaticModeParameters()); + setParameters(AutomaticModeParameters()); } - ScreenLightControl::~ScreenLightControl() + ScreenLightController::~ScreenLightController() { disableTimers(); } - void ScreenLightControl::processRequest(Action action) + void ScreenLightController::processRequest(Action action) { processRequest(action, Parameters()); } - void ScreenLightControl::processRequest(Action action, const Parameters ¶ms) + + void ScreenLightController::processRequest(Action action, const Parameters ¶ms) { switch (action) { case Action::turnOff: @@ -60,65 +61,66 @@ namespace screen_light_control } } - void ScreenLightControl::controlTimerCallback() + void ScreenLightController::controlTimerCallback() { - bsp::eink_frontlight::setBrightness(functions::brightnessRampOut()); + bsp::eink_frontlight::setBrightness(::screen_light_control::functions::brightnessRampOut()); } - void ScreenLightControl::readoutTimerCallback() + void ScreenLightController::readoutTimerCallback() { - functions::calculateBrightness(bsp::light_sensor::readout()); + ::screen_light_control::functions::calculateBrightness(bsp::light_sensor::readout()); } - auto ScreenLightControl::getAutoModeState() const noexcept -> ScreenLightMode + auto ScreenLightController::isLightOn() const noexcept -> bool { - return automaticMode; + return lightOn; } - auto ScreenLightControl::isLightOn() const noexcept -> bool + bool ScreenLightController::isAutoModeOn() const noexcept { - return lightOn; + return automaticMode == ScreenLightMode::Automatic; } - auto ScreenLightControl::getBrightnessValue() const noexcept -> bsp::eink_frontlight::BrightnessPercentage + auto ScreenLightController::getBrightnessValue() const noexcept -> bsp::eink_frontlight::BrightnessPercentage { return brightnessValue; } - void ScreenLightControl::enableTimers() + void ScreenLightController::enableTimers() { controlTimer.start(); readoutTimer.start(); } - void ScreenLightControl::disableTimers() + void ScreenLightController::disableTimers() { controlTimer.stop(); readoutTimer.stop(); } - void ScreenLightControl::setParameters(const AutomaticModeParameters ¶ms) + void ScreenLightController::setParameters(const AutomaticModeParameters ¶ms) { if (lightOn && automaticMode == ScreenLightMode::Automatic) { disableTimers(); } - functions::setRampStep(100.0f * (static_cast(CONTROL_TIMER_MS) / static_cast(params.rampTimeMS))); - functions::setHysteresis(params.brightnessHysteresis); - functions::setFunctionFromPoints(params.functionPoints); + ::screen_light_control::functions::setRampStep( + 100.0f * (static_cast(CONTROL_TIMER_MS) / static_cast(params.rampTimeMS))); + ::screen_light_control::functions::setHysteresis(params.brightnessHysteresis); + ::screen_light_control::functions::setFunctionFromPoints(params.functionPoints); if (lightOn && automaticMode == ScreenLightMode::Automatic) { enableTimers(); } } - void ScreenLightControl::setParameters(ManualModeParameters params) + void ScreenLightController::setParameters(ManualModeParameters params) { brightnessValue = params.manualModeBrightness; setManualBrightnessLevel(); } - void ScreenLightControl::enableAutomaticMode() + void ScreenLightController::enableAutomaticMode() { if (lightOn) { enableTimers(); @@ -126,14 +128,14 @@ namespace screen_light_control automaticMode = ScreenLightMode::Automatic; } - void ScreenLightControl::disableAutomaticMode() + void ScreenLightController::disableAutomaticMode() { disableTimers(); automaticMode = ScreenLightMode::Manual; setManualBrightnessLevel(); } - void ScreenLightControl::turnOn() + void ScreenLightController::turnOn() { bsp::eink_frontlight::turnOn(); bsp::light_sensor::wakeup(); @@ -143,12 +145,12 @@ namespace screen_light_control lightOn = true; } - void ScreenLightControl::setManualBrightnessLevel() + void ScreenLightController::setManualBrightnessLevel() { bsp::eink_frontlight::setBrightness(brightnessValue); } - void ScreenLightControl::turnOff() + void ScreenLightController::turnOff() { bsp::eink_frontlight::turnOff(); bsp::light_sensor::standby(); diff --git a/products/PurePhone/services/evtmgr/screen-light-control/ScreenLightControl.hpp b/products/PurePhone/services/evtmgr/screen-light-control/ScreenLightControl.hpp new file mode 100644 index 0000000000000000000000000000000000000000..36ae0b9ca71d203f20600df7fdab297de3cdeb23 --- /dev/null +++ b/products/PurePhone/services/evtmgr/screen-light-control/ScreenLightControl.hpp @@ -0,0 +1,70 @@ +// 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 +#include + +#include + +#include + +namespace sys +{ + class Service; +} // namespace sys + +/// Screen light control algorithm. Automatic/Manual mode of operation. +/// Processing of ambient light sensor input to screen brightness output. +namespace pure::screen_light_control +{ + /// Control screen light and keeps it's current state + class ScreenLightController : public ::screen_light_control::ScreenLightController + { + public: + using Action = ::screen_light_control::Action; + using Parameters = ::screen_light_control::Parameters; + using ScreenLightMode = ::screen_light_control::ScreenLightMode; + using ManualModeParameters = ::screen_light_control::ManualModeParameters; + using AutomaticModeParameters = ::screen_light_control::AutomaticModeParameters; + using LinearProgressModeParameters = ::screen_light_control::LinearProgressModeParameters; + + explicit ScreenLightController(sys::Service *parent); + ~ScreenLightController() override; + + void processRequest(Action action) override; + void processRequest(Action action, const Parameters ¶ms) override; + + [[nodiscard]] auto isLightOn() const noexcept -> bool override; + [[nodiscard]] bool isAutoModeOn() const noexcept override; + [[nodiscard]] auto getBrightnessValue() const noexcept -> bsp::eink_frontlight::BrightnessPercentage override; + + private: + void controlTimerCallback(); + void readoutTimerCallback(); + + void enableTimers(); + void disableTimers(); + + void setParameters(const AutomaticModeParameters ¶ms); + void setParameters(ManualModeParameters params); + void setManualBrightnessLevel(); + + void turnOff(); + void turnOn(); + + void enableAutomaticMode(); + void disableAutomaticMode(); + + static constexpr inline auto CONTROL_TIMER_MS = 25; + static constexpr inline auto READOUT_TIMER_MS = 500; + + sys::TimerHandle controlTimer; + sys::TimerHandle readoutTimer; + + bool lightOn = false; + ScreenLightMode automaticMode = ScreenLightMode::Manual; + bsp::eink_frontlight::BrightnessPercentage brightnessValue = 0.0; + }; +} // namespace pure::screen_light_control