~aleteoryx/muditaos

muditaos/module-services/service-time/AlarmOperations.hpp -rw-r--r-- 11.0 KiB
a405cad6Aleteoryx trim readme 6 days ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
// Copyright (c) 2017-2024, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/blob/master/LICENSE.md

#pragma once

#include "AlarmRepository.hpp"
#include "SnoozedAlarmEventRecord.hpp"

#include <service-time/AlarmHandlerFactory.hpp>
#include <service-time/AlarmStatus.hpp>

#include <module-db/Interface/AlarmEventRecord.hpp>

#include <Service/Service.hpp>

namespace alarms
{
    class IAlarmOperations
    {
      public:
        using OnGetAlarmProcessed           = std::function<void(AlarmEventRecord)>;
        using OnGetAlarmWithStatusProcessed = std::function<void(std::pair<AlarmEventRecord, AlarmStatus>)>;
        using OnGetAlarmsInRangeProcessed   = std::function<void(std::pair<std::vector<AlarmEventRecord>, uint32_t>)>;
        using OnAddAlarmProcessed           = std::function<void(bool)>;
        using OnUpdateAlarmProcessed        = std::function<void(bool)>;
        using OnRemoveAlarmProcessed        = std::function<void(bool)>;
        using OnGetFirstNextSingleProcessed = std::function<void(SingleEventRecord)>;
        using OnGetAlarmsProcessed          = std::function<void(std::vector<SingleEventRecord>)>;
        using OnSnoozeRingingAlarm          = std::function<void(bool)>;
        using OnTurnOffRingingAlarm         = std::function<void(bool)>;
        using OnGetSnoozedAlarms            = std::function<void(std::vector<SingleEventRecord>)>;
        using OnSnoozedAlarmsCountChange    = std::function<void(unsigned)>;
        using OnActiveAlarmCountChange      = std::function<void(bool)>;
        using OnToggleAllProcessed          = std::function<void(bool)>;
        using CheckIfPhoneCallIsOngoing     = std::function<bool(void)>;
        using OnAlarmDuringPhoneCall        = std::function<void(void)>;
        using OnTurnOffPreWakeUp            = std::function<void(bool)>;

        virtual ~IAlarmOperations() noexcept = default;

        using GetCurrentTime = std::function<TimePoint()>;

        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<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;
        virtual void handleCriticalBatteryLevel()                                                            = 0;
        virtual void handleNormalBatteryLevel()                                                              = 0;
        virtual void addCheckIfPhoneCallIsOngoingCallback(CheckIfPhoneCallIsOngoing)                         = 0;
        virtual void addAlarmDuringPhoneCallCallback(OnAlarmDuringPhoneCall)                                 = 0;
        virtual void turnOffPreWakeUp(OnTurnOffPreWakeUp)                                                    = 0;
    };

    class IAlarmOperationsFactory
    {
      public:
        virtual ~IAlarmOperationsFactory() noexcept = default;

        virtual std::unique_ptr<IAlarmOperations> create(
            sys::Service *service,
            std::unique_ptr<AbstractAlarmEventsRepository> &&alarmEventsRepo,
            IAlarmOperations::GetCurrentTime getCurrentTimeCallback) const = 0;
    };

    class AlarmOperationsCommon : public IAlarmOperations
    {
      public:
        AlarmOperationsCommon(std::unique_ptr<AbstractAlarmEventsRepository> &&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<alarms::AlarmHandler> 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;
        void addCheckIfPhoneCallIsOngoingCallback(CheckIfPhoneCallIsOngoing callback) override;
        void addAlarmDuringPhoneCallCallback(OnAlarmDuringPhoneCall callback) override;
        void turnOffPreWakeUp(OnTurnOffPreWakeUp callback) override;

      protected:
        std::unique_ptr<AbstractAlarmEventsRepository> alarmEventsRepo;
        AlarmHandlerFactory alarmHandlerFactory;

        // Events we are waiting for (on one timepoint)
        std::vector<std::unique_ptr<SingleEventRecord>> nextSingleEvents;
        std::vector<std::unique_ptr<SingleEventRecord>> ongoingSingleEvents;
        std::vector<std::unique_ptr<SnoozedAlarmEventRecord>> snoozedSingleEvents;

        alarms::AlarmType getAlarmEventType(const SingleEventRecord &event);
        virtual void handleAlarmEvent(const std::shared_ptr<AlarmEventRecord> &event,
                                      alarms::AlarmType alarmType,
                                      bool newStateOn);

      private:
        bool isCriticalBatteryLevel{false};
        GetCurrentTime getCurrentTimeCallback;
        OnSnoozedAlarmsCountChange onSnoozedAlarmsCountChangeCallback = nullptr;
        OnActiveAlarmCountChange onActiveAlarmCountChangeCallback     = nullptr;
        CheckIfPhoneCallIsOngoing onCheckIfPhoneCallIsOngoingCallback = nullptr;
        OnAlarmDuringPhoneCall onAlarmDuringPhoneCallCallback         = 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<AlarmEventRecord> records);
        void onRepoGetAlarmsResponse(TimePoint start,
                                     std::vector<AlarmEventRecord> 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<AlarmEventRecord> &event, alarms::AlarmType alarmType);

        TimePoint getCurrentTime();
        void handleSnoozedAlarmsCountChange();
        void handleActiveAlarmsCountChange();
    };

    class CommonAlarmOperationsFactory : public IAlarmOperationsFactory
    {
      public:
        std::unique_ptr<IAlarmOperations> create(
            sys::Service *service,
            std::unique_ptr<AbstractAlarmEventsRepository> &&alarmEventsRepo,
            IAlarmOperations::GetCurrentTime getCurrentTimeCallback) const override;
    };

    auto findSingleEventById(std::vector<std::unique_ptr<SingleEventRecord>> &events, const std::uint32_t id)
        -> std::vector<std::unique_ptr<SingleEventRecord>>::iterator;
    auto findSnoozedEventById(std::vector<std::unique_ptr<SnoozedAlarmEventRecord>> &events, const std::uint32_t id)
        -> std::vector<std::unique_ptr<SnoozedAlarmEventRecord>>::iterator;
} // namespace alarms