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