1 /*
2  * Copyright (c) 2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 #ifndef UPDATER_INIT_H
16 #define UPDATER_INIT_H
17 
18 #include <vector>
19 #include "macros_updater.h"
20 
21 namespace Updater {
22 enum UpdaterInitEvent {
23     // main
24     UPDATER_MAIN_PRE_EVENT = 0,
25 
26     // updater
27     UPDATER_PRE_INIT_EVENT,
28     UPDATER_INIT_EVENT,
29     UPDATER_PRE_VERIFY_EVENT,
30     UPDATER_POST_INIT_EVENT,
31 
32     // flashd
33     FLAHSD_PRE_INIT_EVENT,
34 
35     // binary
36     UPDATER_BINARY_INIT_EVENT,
37     UPDATER_BINARY_INIT_DONE_EVENT,
38 
39     // factory reset
40     FACTORY_RESET_INIT_EVENT,
41 
42     UPDATER_INIT_EVENT_BUTT
43 };
44 
45 using InitHandler = void (*)(void);
46 
47 class UpdaterInit {
48     DISALLOW_COPY_MOVE(UpdaterInit);
49 public:
GetInstance()50     static UpdaterInit &GetInstance()
51     {
52         static UpdaterInit instance;
53         return instance;
54     }
InvokeEvent(enum UpdaterInitEvent eventId)55     void InvokeEvent(enum UpdaterInitEvent eventId) const
56     {
57         if (eventId >= UPDATER_INIT_EVENT_BUTT) {
58             return;
59         }
60         for (const auto &handler : initEvent_[eventId]) {
61             if (handler != nullptr) {
62                 handler();
63             }
64         }
65     }
SubscribeEvent(enum UpdaterInitEvent eventId,InitHandler handler)66     void SubscribeEvent(enum UpdaterInitEvent eventId, InitHandler handler)
67     {
68         if (eventId < UPDATER_INIT_EVENT_BUTT) {
69             initEvent_[eventId].push_back(handler);
70         }
71     }
72 private:
73     UpdaterInit() = default;
74     ~UpdaterInit() = default;
75     std::vector<InitHandler> initEvent_[UPDATER_INIT_EVENT_BUTT];
76 };
77 
78 #define DEFINE_INIT_EVENT(name, event, ...)                                      \
79     static void name##_##event##_Init(void)                                      \
80     {                                                                            \
81         __VA_ARGS__;                                                             \
82     }                                                                            \
83     __attribute((constructor)) static void Register_##name##_##event(void)       \
84     {                                                                            \
85         UpdaterInit::GetInstance().SubscribeEvent(event, name##_##event##_Init); \
86     }                                                                            \
87     static_assert(true)
88 
89 // mode related macro
90 #define MODE_ENTRY(name) name##Main
91 
92 #define MODE_CONDITION(name) Is##name
93 
94 #define BOOT_MODE(name, para) BootMode { MODE_CONDITION(name), STRINGFY(name), para, MODE_ENTRY(name) }
95 
96 #define REGISTER_MODE(name, para, ...) \
97     DEFINE_INIT_EVENT(name, UPDATER_MAIN_PRE_EVENT, RegisterMode(BOOT_MODE(name, para)))
98 }
99 
100 #endif