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_UPDATE_PACKAGE_EVENT,
30     UPDATER_POST_UPDATE_PACKAGE_EVENT,
31     UPDATER_POST_INIT_EVENT,
32 
33     // flashd
34     FLAHSD_PRE_INIT_EVENT,
35 
36     // binary
37     UPDATER_BINARY_INIT_EVENT,
38     UPDATER_BINARY_INIT_DONE_EVENT,
39 
40     // factory reset
41     FACTORY_RESET_INIT_EVENT,
42 
43     UPDATER_INIT_EVENT_BUTT
44 };
45 
46 using InitHandler = void (*)(void);
47 
48 class UpdaterInit {
49     DISALLOW_COPY_MOVE(UpdaterInit);
50 public:
GetInstance()51     static UpdaterInit &GetInstance()
52     {
53         static UpdaterInit instance;
54         return instance;
55     }
InvokeEvent(enum UpdaterInitEvent eventId) const56     void InvokeEvent(enum UpdaterInitEvent eventId) const
57     {
58         if (eventId >= UPDATER_INIT_EVENT_BUTT) {
59             return;
60         }
61         for (const auto &handler : initEvent_[eventId]) {
62             if (handler != nullptr) {
63                 handler();
64             }
65         }
66     }
SubscribeEvent(enum UpdaterInitEvent eventId, InitHandler handler)67     void SubscribeEvent(enum UpdaterInitEvent eventId, InitHandler handler)
68     {
69         if (eventId < UPDATER_INIT_EVENT_BUTT) {
70             initEvent_[eventId].push_back(handler);
71         }
72     }
73 private:
74     UpdaterInit() = default;
75     ~UpdaterInit() = default;
76     std::vector<InitHandler> initEvent_[UPDATER_INIT_EVENT_BUTT];
77 };
78 
79 #define DEFINE_INIT_EVENT(name, event, ...)                                      \
80     static void name##_##event##_Init(void)                                      \
81     {                                                                            \
82         __VA_ARGS__;                                                             \
83     }                                                                            \
84     __attribute((constructor)) static void Register_##name##_##event(void)       \
85     {                                                                            \
86         UpdaterInit::GetInstance().SubscribeEvent(event, name##_##event##_Init); \
87     }                                                                            \
88     static_assert(true)
89 
90 // mode related macro
91 #define MODE_ENTRY(name) name##Main
92 
93 #define MODE_CONDITION(name) Is##name
94 
95 #define BOOT_MODE(name, para) BootMode { MODE_CONDITION(name), STRINGFY(name), para, MODE_ENTRY(name) }
96 
97 #define REGISTER_MODE(name, para, ...) \
98     DEFINE_INIT_EVENT(name, UPDATER_MAIN_PRE_EVENT, RegisterMode(BOOT_MODE(name, para)))
99 }
100 
101 #endif