~aleteoryx/muditaos

ref: 48d31b876cf6fed438676e4fa73b6e16b1f6b3a7 muditaos/module-sys/SystemManager/SystemManager.hpp -rw-r--r-- 8.0 KiB
48d31b87 — tomaszkrosnowski [EGD-6311] Audio settings windows 4 years 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
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

/*
 * Service.hpp
 *
 *  Created on: Mar 7, 2019
 *      Author: mati
 */

#ifndef SYSTEMMANAGER_SYSTEMMANAGER_HPP_
#define SYSTEMMANAGER_SYSTEMMANAGER_HPP_

#include <functional>
#include <stdexcept>
#include "thread.hpp"
#include "condition_variable.hpp"
#include "mutex.hpp"
#include "Service/Mailbox.hpp"
#include "Service/Service.hpp"
#include "Service/ServiceCreator.hpp"
#include "Timers/TimerHandle.hpp"
#include "PowerManager.hpp"
#include "PhoneModes/Subject.hpp"
#include <common_data/RawKey.hpp>
#include "Constants.hpp"
#include "CpuStatistics.hpp"
#include "DeviceManager.hpp"
#include <chrono>
#include <vector>

namespace sys
{
    namespace constants
    {
        using namespace std::chrono_literals;
        inline constexpr std::chrono::milliseconds timerInitInterval{30s};
        inline constexpr std::chrono::milliseconds timerPeriodInterval{100ms};
        inline constexpr auto restoreTimeout{5000};
    } // namespace constants

    class PhoneModeRequest; // Forward declaration
    class TetheringStateRequest; // Forward declaration

    enum class Code
    {
        CloseSystem,
        Update,
        Restore,
        Reboot,
        None,
    };

    class SystemInitialisationError : public std::runtime_error
    {
      public:
        using std::runtime_error::runtime_error;
    };

    class SystemManagerCmd : public DataMessage
    {
      public:
        explicit SystemManagerCmd(Code type = Code::None, CloseReason closeReason = CloseReason::RegularPowerDown)
            : DataMessage(BusChannel::SystemManagerRequests), type(type), closeReason(closeReason)
        {}

        Code type;
        CloseReason closeReason;
    };

    class SystemManager : public Service
    {
      public:
        using InitFunction = std::function<bool()>;

        enum class State
        {
            Running,
            Suspend,
            Shutdown,
            ShutdownReady,
            Reboot
        } state = State::Running;

        explicit SystemManager(std::vector<std::unique_ptr<BaseServiceCreator>> &&creators);
        ~SystemManager() override;

        void set(enum State state);

        void initialize();

        void StartSystem(InitFunction sysInit, InitFunction appSpaceInit);

        // Invoke system close procedure
        static bool CloseSystem(Service *s);

        static bool Update(Service *s, const std::string &updateOSVer, const std::string &currentOSVer);

        static bool Restore(Service *s);

        static bool Reboot(Service *s);

        static void storeOsVersion(Service *s, const std::string &updateOSVer, const std::string &currentOSVer);

        static bool SuspendService(const std::string &name, Service *caller);

        static bool ResumeService(const std::string &name, Service *caller);

        /// Runs a service
        static bool RunSystemService(std::shared_ptr<Service> service, Service *caller, TickType_t timeout = 5000);
        /// Runs an application
        static bool RunApplication(std::shared_ptr<Service> service, Service *caller, TickType_t timeout = 5000);

        /// Destroy existing service
        /// @note there is no fallback
        static bool DestroySystemService(const std::string &name, Service *caller, TickType_t timeout = 5000);
        /// Destroy existing application
        static bool DestroyApplication(const std::string &name, Service *caller, TickType_t timeout = 5000);

        /// Translates a slider state into a phone mode.
        /// \param key  Slider button state
        /// \return Phone mode.
        static phone_modes::PhoneMode translateSliderState(const RawKey &key);

        /// Kill service
        /// @note - this is final, it straight takes service, calls it's close callback and it's gone
        /// please mind that services & apps not registered in SystemManager cant be killed - these should be handled by
        /// parents (as above in Destroy) ApplicationManager somehow propagates this, but I would call how it's done
        /// `imperfect`
        ///
        /// @note there is no timeout on deinit handler, might be worth to consider blocking `message` DeinitHandler
        /// instead
        void kill(std::shared_ptr<Service> const &toKill);

      private:
        MessagePointer DataReceivedHandler(DataMessage *msg, ResponseMessage *resp) override;

        ReturnCodes InitHandler() override;

        ReturnCodes DeinitHandler() override
        {
            return ReturnCodes::Success;
        }

        ReturnCodes SwitchPowerModeHandler(const ServicePowerMode mode) final
        {
            return ReturnCodes::Success;
        }

        void Run() override;

        void StartSystemServices();

        static bool RunService(std::shared_ptr<Service> service, Service *caller, TickType_t timeout = 5000);
        static bool DestroyService(std::vector<std::shared_ptr<Service>> &serviceContainer,
                                   const std::string &name,
                                   Service *caller,
                                   TickType_t timeout = 5000);

        /// Sysmgr stores list of all active services but some of them are under control of parent services.
        /// Parent services ought to manage lifetime of child services hence we are sending DestroyRequests only to
        /// parents.
        /// It closes all workers except EventManager -as it needs information from Eventmanager that it's safe to
        /// shutdown
        void CloseSystemHandler(CloseReason closeReason = CloseReason::RegularPowerDown);

        void CloseServices();

        void preCloseRoutine(CloseReason closeReason);

        void postStartRoutine();

        void readyToCloseHandler(Message *msg);

        void UpdateSystemHandler();

        void RestoreSystemHandler();

        void RebootHandler();

        /// loop to handle prior to full system close
        /// for now for rt1051 we need to
        /// 1. check if we have power plug in
        /// 2. if power is in, if we didn't get request for poweron ( this triggers reboot)
        /// this is needed as we can't just shutdown phone with power in - it would end in phone unable to boot (as
        /// red key won't work to power it on. For more information follow up with schematics
        bool PreShutdownLoop();

        /// periodic update of cpu statistics
        void CpuStatisticsTimerHandler();

        MessagePointer handlePhoneModeRequest(PhoneModeRequest *request);
        MessagePointer handleTetheringStateRequest(TetheringStateRequest *request);

        void batteryCriticalLevelAction(bool charging);
        void batteryNormalLevelAction();
        void batteryShutdownLevelAction();

        bool cpuStatisticsTimerInit{false};

        std::vector<std::unique_ptr<BaseServiceCreator>> systemServiceCreators;
        sys::TimerHandle cpuStatisticsTimer;
        sys::TimerHandle servicesPreShutdownRoutineTimeout;
        sys::TimerHandle lowBatteryShutdownDelay;
        std::unique_ptr<phone_modes::Subject> phoneModeSubject;
        InitFunction userInit;
        InitFunction systemInit;
        std::vector<std::string> readyForCloseRegister;

        static std::vector<std::shared_ptr<Service>> servicesList;
        static std::vector<std::shared_ptr<Service>> applicationsList;
        static cpp_freertos::MutexStandard destroyMutex;
        static std::unique_ptr<PowerManager> powerManager;
        static std::unique_ptr<CpuStatistics> cpuStatistics;
        static std::unique_ptr<DeviceManager> deviceManager;
    };
} // namespace sys

inline const char *c_str(sys::SystemManager::State state)
{
    switch (state) {
    case sys::SystemManager::State::Running:
        return "Running";
    case sys::SystemManager::State::Suspend:
        return "Suspend";
    case sys::SystemManager::State::Shutdown:
        return "Shutdown";
    case sys::SystemManager::State::Reboot:
        return "Reboot";
    case sys::SystemManager::State::ShutdownReady:
        return "ShutdownReady";
    }
    return "";
}

#endif /* SYSTEMMANAGER_SYSTEMMANAGER_HPP_ */