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