// Copyright (c) 2017-2023, Mudita Sp. z.o.o. All rights reserved. // For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md #pragma once #include "AlarmRepository.hpp" #include "SnoozedAlarmEventRecord.hpp" #include #include #include #include namespace alarms { class IAlarmOperations { public: using OnGetAlarmProcessed = std::function; using OnGetAlarmWithStatusProcessed = std::function)>; using OnGetAlarmsInRangeProcessed = std::function, uint32_t>)>; using OnAddAlarmProcessed = std::function; using OnUpdateAlarmProcessed = std::function; using OnRemoveAlarmProcessed = std::function; using OnGetFirstNextSingleProcessed = std::function; using OnGetAlarmsProcessed = std::function)>; using OnSnoozeRingingAlarm = std::function; using OnTurnOffRingingAlarm = std::function; using OnGetSnoozedAlarms = std::function)>; using OnSnoozedAlarmsCountChange = std::function; using OnActiveAlarmCountChange = std::function; using OnToggleAllProcessed = std::function; virtual ~IAlarmOperations() noexcept = default; using GetCurrentTime = std::function; virtual void updateEventsCache(TimePoint now) = 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 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; virtual void snoozeRingingAlarm(const std::uint32_t id, const TimePoint nextAlarmTime, OnSnoozeRingingAlarm callback) = 0; virtual void postponeSnooze(const std::uint32_t id, const TimePoint nextAlarmTime, OnSnoozeRingingAlarm callback) = 0; virtual void minuteUpdated(TimePoint now) = 0; virtual void addAlarmExecutionHandler(const alarms::AlarmType type, const std::shared_ptr 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; virtual void handleCriticalBatteryLevel() = 0; virtual void handleNormalBatteryLevel() = 0; }; class IAlarmOperationsFactory { public: virtual ~IAlarmOperationsFactory() noexcept = default; virtual std::unique_ptr create( sys::Service *service, std::unique_ptr &&alarmEventsRepo, IAlarmOperations::GetCurrentTime getCurrentTimeCallback) const = 0; }; class AlarmOperationsCommon : public IAlarmOperations { public: AlarmOperationsCommon(std::unique_ptr &&alarmEventsRepo, GetCurrentTime getCurrentTimeCallback); void updateEventsCache(TimePoint now) override; void getAlarm(const std::uint32_t alarmId, OnGetAlarmProcessed callback) override; void getAlarmWithStatus(const std::uint32_t alarmId, OnGetAlarmWithStatusProcessed callback) override; void addAlarm(AlarmEventRecord record, OnAddAlarmProcessed callback) override; void updateAlarm(AlarmEventRecord record, OnUpdateAlarmProcessed callback) override; void removeAlarm(const std::uint32_t alarmId, OnRemoveAlarmProcessed callback) override; void getAlarmsInRange(std::uint32_t offset, std::uint32_t limit, OnGetAlarmsInRangeProcessed callback) override; void getNextSingleEvents(TimePoint start, OnGetAlarmsProcessed callback) override; void turnOffRingingAlarm(const std::uint32_t id, OnTurnOffRingingAlarm callback) override; void turnOffSnoozedAlarm(const std::uint32_t id, OnTurnOffRingingAlarm callback) override; void snoozeRingingAlarm(const std::uint32_t id, const TimePoint nextAlarmTime, OnSnoozeRingingAlarm callback) override; void postponeSnooze(const std::uint32_t id, const TimePoint nextAlarmTime, OnSnoozeRingingAlarm callback) override; void minuteUpdated(TimePoint now) override; void addAlarmExecutionHandler(const alarms::AlarmType type, const std::shared_ptr handler) override; void stopAllSnoozedAlarms() override; void addSnoozedAlarmsCountChangeCallback(OnSnoozedAlarmsCountChange callback) override; void addActiveAlarmCountChangeCallback(OnActiveAlarmCountChange callback) override; void toggleAll(bool toggle, OnToggleAll callback) override; void getSnoozedAlarms(OnGetSnoozedAlarms callback) override; void handleCriticalBatteryLevel() override; void handleNormalBatteryLevel() override; protected: std::unique_ptr alarmEventsRepo; AlarmHandlerFactory alarmHandlerFactory; // Events we are waiting for (on one timepoint) std::vector> nextSingleEvents; std::vector> ongoingSingleEvents; std::vector> snoozedSingleEvents; alarms::AlarmType getAlarmEventType(const SingleEventRecord &event); virtual void handleAlarmEvent(const std::shared_ptr &event, alarms::AlarmType alarmType, bool newStateOn); private: bool isCriticalBatteryLevel{false}; GetCurrentTime getCurrentTimeCallback; OnSnoozedAlarmsCountChange onSnoozedAlarmsCountChangeCallback = nullptr; OnActiveAlarmCountChange onActiveAlarmCountChangeCallback = nullptr; // Max 100 alarms for one minute seems reasonable, next events will be dropped constexpr static auto getNextSingleEventsOffset = 0; constexpr static auto getNextSingleEventsLimit = 100; void onRepoGetFirstNextSingeResponse(OnGetFirstNextSingleProcessed handledCallback, TimePoint start, std::vector records); void onRepoGetAlarmsResponse(TimePoint start, std::vector records, OnGetAlarmsProcessed handledCallback); void checkAndUpdateCache(AlarmEventRecord record); void switchAlarmExecution(const SingleEventRecord &singleAlarmEvent, bool newStateOn); void processEvents(TimePoint now); void processOngoingEvents(); void processNextEventsQueue(const TimePoint now); void processSnoozedEventsQueue(const TimePoint now); void stopAllRingingAlarms(); void triggerAlarm(); virtual void onAlarmTurnedOff(const std::shared_ptr &event, alarms::AlarmType alarmType); TimePoint getCurrentTime(); void handleSnoozedAlarmsCountChange(); void handleActiveAlarmsCountChange(); }; class CommonAlarmOperationsFactory : public IAlarmOperationsFactory { public: std::unique_ptr create( sys::Service *service, std::unique_ptr &&alarmEventsRepo, IAlarmOperations::GetCurrentTime getCurrentTimeCallback) const override; }; auto findSingleEventById(std::vector> &events, const std::uint32_t id) -> std::vector>::iterator; auto findSnoozedEventById(std::vector> &events, const std::uint32_t id) -> std::vector>::iterator; } // namespace alarms