1 /*
2  * Copyright (c) 2022-2024 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 
16 #ifndef RESSCHED_SERVICES_RESSCHEDMGR_RESSCHEDFWK_INCLUDE_PLUGIN_MGR_H
17 #define RESSCHED_SERVICES_RESSCHEDMGR_RESSCHEDFWK_INCLUDE_PLUGIN_MGR_H
18 
19 #include <functional>
20 #include <list>
21 #include <string>
22 #include <memory>
23 #include <map>
24 #include <vector>
25 #include "datetime_ex.h"
26 #include "event_handler.h"
27 #include "config_reader.h"
28 #include "plugin_switch.h"
29 #include "plugin.h"
30 #include "nocopyable.h"
31 #include "res_data.h"
32 #include "single_instance.h"
33 #include "config_info.h"
34 #ifdef RESOURCE_SCHEDULE_SERVICE_WITH_FFRT_ENABLE
35 #include "ffrt.h"
36 #endif
37 #ifdef RESOURCE_SCHEDULE_SERVICE_WITH_EXT_RES_ENABLE
38 #include "res_type.h"
39 #endif
40 
41 namespace OHOS {
42 namespace ResourceSchedule {
43 using Clock = std::chrono::high_resolution_clock;
44 using TimePoint = std::chrono::time_point<Clock>;
45 using OnPluginInitFunc = bool (*)(std::string&);
46 using OnDispatchResourceFunc = void (*)(const std::shared_ptr<ResData>&);
47 using OnDeliverResourceFunc = int32_t (*)(const std::shared_ptr<ResData>&);
48 using OnDumpFunc = void (*)(const std::vector<std::string>&, std::string&);
49 using OnPluginDisableFunc = void (*)();
50 using OnIsAllowedAppPreloadFunc = bool (*)(const std::string&, int32_t preloadMode);
51 using GetExtMultiConfigFunc = int32_t (*)(int32_t, std::vector<std::string>&);
52 
53 constexpr int32_t DISPATCH_TIME_OUT = 50; // ms
54 constexpr int32_t DISPATCH_TIME_OUT_US = DISPATCH_TIME_OUT * 1000; // us
55 constexpr int32_t PLUGIN_STAT_MAX_USE_COUNT = 1000;
56 
57 struct PluginStat {
58     uint64_t totalTime;
59     uint64_t useCount;
60     std::list<TimePoint> timeOutTime;
61 
UpdatePluginStat62     inline void Update(int32_t costTime)
63     {
64         if (costTime > 0 && costTime < DISPATCH_TIME_OUT_US) {
65             if (totalTime + (uint32_t)costTime < totalTime) {
66                 totalTime = (uint32_t)costTime;
67                 useCount = 1;
68             } else {
69                 totalTime += (uint32_t)costTime;
70                 useCount += 1;
71             }
72         }
73     }
74 
AverageTimePluginStat75     inline uint64_t AverageTime()
76     {
77         return (useCount > 0) ? (totalTime / useCount) : 0;
78     }
79 };
80 
81 struct PluginLib {
82     std::shared_ptr<void> handle = nullptr;
83     OnPluginInitFunc onPluginInitFunc_;
84     OnDispatchResourceFunc onDispatchResourceFunc_;
85     OnDeliverResourceFunc onDeliverResourceFunc_;
86     OnDumpFunc onDumpFunc_;
87     OnPluginDisableFunc onPluginDisableFunc_;
88 };
89 
90 class PluginMgr {
91     DECLARE_SINGLE_INSTANCE_BASE(PluginMgr);
92 
93 public:
94     ~PluginMgr();
95 
96     /**
97      * Init pluginmanager, load xml config file, construct plugin instances.
98      *
99      * @param isRssExe Calling service is resource schedule executor.
100      */
101     void Init(bool isRssExe = false);
102 
103     /**
104      * Disable all plugins, maybe service exception happens or stopped.
105      */
106     void Stop();
107 
108     /**
109      * receive all reported resource data, then dispatch all plugins.
110      *
111      * @param resData Reported resource data.
112      */
113     void DispatchResource(const std::shared_ptr<ResData>& resData);
114 
115     /**
116      * receive all reported sync resource data, then deliver to plugins.
117      *
118      * @param resData Reported resource data.
119      */
120     int32_t DeliverResource(const std::shared_ptr<ResData>& resData);
121 
122     /**
123      * Subscribe resource type from plugin.
124      *
125      * @param pluginLib The lib name of plugin.
126      * @param resType interested in resource type.
127      */
128     void SubscribeResource(const std::string& pluginLib, uint32_t resType);
129 
130     /**
131      * Unsubscribe resource type from plugin.
132      *
133      * @param pluginLib The lib name of plugin.
134      * @param resType interested in resource type.
135      */
136     void UnSubscribeResource(const std::string& pluginLib, uint32_t resType);
137 
138     /**
139      * Subscribe sync resource type from plugin.
140      *
141      * @param pluginLib The lib name of plugin.
142      * @param resType interested in resource type.
143      */
144     void SubscribeSyncResource(const std::string& pluginLib, uint32_t resType);
145 
146     /**
147      * Unsubscribe sync resource type from plugin.
148      *
149      * @param pluginLib The lib name of plugin.
150      * @param resType interested in resource type.
151      */
152     void UnSubscribeSyncResource(const std::string& pluginLib, uint32_t resType);
153 
154     /**
155      * Kill process by pid.
156      *
157      * @param payload process message.
158      */
159     void KillProcessByPid(const nlohmann::json& payload, std::string killClientInitiator);
160 
161     void DumpAllPlugin(std::string &result);
162 
163     void DumpAllPluginConfig(std::string &result);
164 
165     void DumpOnePlugin(std::string &result, std::string pluginName, std::vector<std::string>& args);
166 
167     std::string DumpInfoFromPlugin(std::string& result, std::string libPath, std::vector<std::string>& args);
168 
169     void DumpHelpFromPlugin(std::string& result);
170 
171     PluginConfig GetConfig(const std::string& pluginName, const std::string& configName);
172 
173     void SetResTypeStrMap(const std::map<uint32_t, std::string>& resTypeStr);
174 
175     std::shared_ptr<PluginLib> GetPluginLib(const std::string& libPath);
176 
177     void GetConfigContent(int32_t configIdx, const std::string& configPath, std::vector<std::string>& contents);
178 
179     /**
180      * Get config reader xml file.
181      *
182      * @return config reader xml file string.
183      */
184     std::vector<std::string> GetConfigReaderStr();
185 
186     /**
187      * Get plugin switch xml file.
188      *
189      * @return plugin switch xml file string.
190      */
191     std::vector<std::string> GetPluginSwitchStr();
192 
193     /**
194      * Parse config reader xml file.
195      *
196      * @param configStr The string of config reader xml file.
197      */
198     void ParseConfigReader(const std::vector<std::string>& configStrs);
199 
200     /**
201      * Parse plugin switch xml file.
202      *
203      * @param switchStr The string of plugin switch xml file.
204      * @param isRssExe is calling service resource_schedule_executor.
205      */
206     void ParsePluginSwitch(const std::vector<std::string>& switchStrs, bool isRssExe = false);
207 
208 private:
209     PluginMgr() = default;
210     void OnDestroy();
211     void LoadPlugin();
212     void LoadGetExtConfigFunc();
213     std::shared_ptr<PluginLib> LoadOnePlugin(const PluginInfo& info);
214     void UnLoadPlugin();
215     void ClearResource();
216     void DispatchResourceToPluginSync(const std::list<std::string>& pluginList,
217         const std::shared_ptr<ResData>& resData);
218 #ifdef RESOURCE_SCHEDULE_SERVICE_WITH_FFRT_ENABLE
219     void DispatchResourceToPluginAsync(const std::list<std::string>& pluginList,
220         const std::shared_ptr<ResData>& resData);
221 #endif
222     void RepairPlugin(TimePoint endTime, const std::string& pluginLib, PluginLib libInfo);
223     void RemoveDisablePluginHandler();
224     void DumpPluginInfoAppend(std::string &result, PluginInfo info);
225     bool GetPluginListByResType(uint32_t resType, std::list<std::string>& pluginList);
226     bool CheckRealPath(const std::string& partialPath, std::string& fullPath);
227     std::vector<std::string> GetAllRealConfigPath(const std::string& configName);
228     std::string BuildDispatchTrace(const std::shared_ptr<ResData>& resData, std::string& libNameAll,
229         const std::string& funcName, std::list<std::string>& pluginList);
230 #ifdef RESOURCE_SCHEDULE_SERVICE_WITH_EXT_RES_ENABLE
231     int32_t GetExtTypeByResPayload(const std::shared_ptr<ResData>& resData);
232 #endif
233     std::list<std::string> SortPluginList(const std::list<std::string>& pluginList);
234     std::string GetStrFromResTypeStrMap(uint32_t resType);
235 
236     class InnerTimeUtil {
237     public:
238         InnerTimeUtil(const std::string& func, const std::string& plugin);
239         ~InnerTimeUtil();
240     private:
241         TimePoint beginTime_;
242         std::string functionName_;
243         std::string pluginName_;
244     };
245 
246     // plugin crash 3 times in 60s, will be disable forever
247     const int32_t MAX_PLUGIN_TIMEOUT_TIMES = 3;
248     const int32_t DISABLE_PLUGIN_TIME = 60000;
249     const int32_t DUMP_ONE_STRING_SIZE = 32;
250     std::unique_ptr<ConfigReader> configReader_ = nullptr;
251     std::unique_ptr<PluginSwitch> pluginSwitch_ = nullptr;
252 
253     std::map<std::string, PluginLib> pluginLibMap_;
254 
255     // mutex for resTypeMap_
256     std::mutex resTypeMutex_;
257     // mutex for resTypeLibSyncMap_
258     std::mutex resTypeSyncMutex_;
259     // mutex for resTypeStrMap_
260     std::mutex resTypeStrMutex_;
261     std::mutex pluginMutex_;
262     std::mutex dispatcherHandlerMutex_;
263     std::mutex libPathMutex_;
264     std::map<uint32_t, std::list<std::string>> resTypeLibMap_;
265     std::map<uint32_t, std::string> resTypeLibSyncMap_;
266     std::map<uint32_t, std::string> resTypeStrMap_;
267 
268 #ifdef RESOURCE_SCHEDULE_SERVICE_WITH_FFRT_ENABLE
269     std::map<std::string, std::shared_ptr<ffrt::queue>> dispatchers_;
270 #else
271     std::shared_ptr<AppExecFwk::EventHandler> dispatcher_ = nullptr;
272 #endif
273 
274     std::map<std::string, PluginStat> pluginStat_;
275     GetExtMultiConfigFunc getExtMultiConfigFunc_ = nullptr;
276 };
277 } // namespace ResourceSchedule
278 } // namespace OHOS
279 
280 #endif // RESSCHED_SERVICES_RESSCHEDMGR_RESSCHEDFWK_INCLUDE_PLUGIN_MGR_H
281