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