/* * Copyright (c) 2022-2023 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef RESSCHED_SERVICES_RESSCHEDMGR_RESSCHEDFWK_INCLUDE_PLUGIN_MGR_H #define RESSCHED_SERVICES_RESSCHEDMGR_RESSCHEDFWK_INCLUDE_PLUGIN_MGR_H #include #include #include #include #include #include #include #include #include "datetime_ex.h" #include "event_handler.h" #include "config_reader.h" #include "plugin_switch.h" #include "plugin.h" #include "nocopyable.h" #include "res_data.h" #include "single_instance.h" #include "config_info.h" #include "ffrt.h" #ifdef RESOURCE_SCHEDULE_SERVICE_WITH_EXT_RES_ENABLE #include "res_type.h" #endif namespace OHOS { namespace ResourceSchedule { using Clock = std::chrono::high_resolution_clock; using TimePoint = std::chrono::time_point; using OnPluginInitFunc = bool (*)(std::string&); using OnDispatchResourceFunc = void (*)(const std::shared_ptr&); using OnDeliverResourceFunc = int32_t (*)(const std::shared_ptr&); using OnDumpFunc = void (*)(const std::vector&, std::string&); using OnPluginDisableFunc = void (*)(); using OnIsAllowedAppPreloadFunc = bool (*)(const std::string&, int32_t preloadMode); using GetExtMultiConfigFunc = int32_t (*)(int32_t, std::vector&); constexpr int32_t DISPATCH_TIME_OUT = 50; // ms constexpr int32_t DISPATCH_TIME_OUT_US = DISPATCH_TIME_OUT * 1000; // us constexpr int32_t PLUGIN_STAT_MAX_USE_COUNT = 1000; struct PluginStat { uint64_t totalTime; uint64_t useCount; std::list timeOutTime; inline void Update(int32_t costTime) { if (costTime > 0 && costTime < DISPATCH_TIME_OUT_US) { if (totalTime + (uint32_t)costTime < totalTime) { totalTime = (uint32_t)costTime; useCount = 1; } else { totalTime += (uint32_t)costTime; useCount += 1; } } } inline uint64_t AverageTime() { return (useCount > 0) ? (totalTime / useCount) : 0; } }; struct PluginLib { std::shared_ptr handle = nullptr; OnPluginInitFunc onPluginInitFunc_; OnDispatchResourceFunc onDispatchResourceFunc_; OnDeliverResourceFunc onDeliverResourceFunc_; OnDumpFunc onDumpFunc_; OnPluginDisableFunc onPluginDisableFunc_; }; class PluginMgr { DECLARE_SINGLE_INSTANCE_BASE(PluginMgr); public: ~PluginMgr(); /** * Init pluginmanager, load xml config file, construct plugin instances. * * @param isRssExe Calling service is resource schedule executor. */ void Init(bool isRssExe = false); /** * Disable all plugins, maybe service exception happens or stopped. */ void Stop(); /** * receive all reported resource data, then dispatch all plugins. * * @param resData Reported resource data. */ void DispatchResource(const std::shared_ptr& resData); /** * receive all reported sync resource data, then deliver to plugins. * * @param resData Reported resource data. */ int32_t DeliverResource(const std::shared_ptr& resData); /** * Subscribe resource type from plugin. * * @param pluginLib The lib name of plugin. * @param resType interested in resource type. */ void SubscribeResource(const std::string& pluginLib, uint32_t resType); /** * Unsubscribe resource type from plugin. * * @param pluginLib The lib name of plugin. * @param resType interested in resource type. */ void UnSubscribeResource(const std::string& pluginLib, uint32_t resType); /** * Subscribe sync resource type from plugin. * * @param pluginLib The lib name of plugin. * @param resType interested in resource type. */ void SubscribeSyncResource(const std::string& pluginLib, uint32_t resType); /** * Unsubscribe sync resource type from plugin. * * @param pluginLib The lib name of plugin. * @param resType interested in resource type. */ void UnSubscribeSyncResource(const std::string& pluginLib, uint32_t resType); /** * Kill process by pid. * * @param payload process message. */ void KillProcessByPid(const nlohmann::json& payload, std::string killClientInitiator); void DumpAllPlugin(std::string &result); void DumpAllPluginConfig(std::string &result); void DumpOnePlugin(std::string &result, std::string pluginName, std::vector& args); std::string DumpInfoFromPlugin(std::string& result, std::string libPath, std::vector& args); void DumpHelpFromPlugin(std::string& result); PluginConfig GetConfig(const std::string& pluginName, const std::string& configName); void SetResTypeStrMap(const std::map& resTypeStr); std::shared_ptr GetPluginLib(const std::string& libPath); void GetConfigContent(int32_t configIdx, const std::string& configPath, std::vector& contents); /** * Get config reader xml file. * * @return config reader xml file string. */ std::vector GetConfigReaderStr(); /** * Get plugin switch xml file. * * @return plugin switch xml file string. */ std::vector GetPluginSwitchStr(); /** * Parse config reader xml file. * * @param configStr The string of config reader xml file. */ void ParseConfigReader(const std::vector& configStrs); /** * Parse plugin switch xml file. * * @param switchStr The string of plugin switch xml file. * @param isRssExe is calling service resource_schedule_executor. */ void ParsePluginSwitch(const std::vector& switchStrs, bool isRssExe = false); /** * set plugin blocked time. * * @param time over time will be judge blocked */ void SetBlockedTime(const int64_t time); private: PluginMgr() = default; void OnDestroy(); void LoadPlugin(); void LoadGetExtConfigFunc(); std::shared_ptr LoadOnePlugin(const PluginInfo& info); void UnLoadPlugin(); void ClearResource(); void DispatchResourceToPluginSync(const std::list& pluginList, const std::shared_ptr& resData); #ifdef RESOURCE_SCHEDULE_SERVICE_WITH_FFRT_ENABLE void DispatchResourceToPluginAsync(const std::list& pluginList, const std::shared_ptr& resData); void HandlePluginTimeout(const std::string& pluginLib); void EnablePluginIfResume(const std::string& pluginLib); void RecordRinningStat(std::string pluginLib, bool isRunning); bool IsPluginRunning(const std::string& pluginLib); #endif void RepairPlugin(TimePoint endTime, const std::string& pluginLib, PluginLib libInfo); void RemoveDisablePluginHandler(); void DumpPluginInfoAppend(std::string &result, PluginInfo info); bool GetPluginListByResType(uint32_t resType, std::list& pluginList); bool CheckRealPath(const std::string& partialPath, std::string& fullPath); std::vector GetAllRealConfigPath(const std::string& configName); std::string BuildDispatchTrace(const std::shared_ptr& resData, std::string& libNameAll, const std::string& funcName, std::list& pluginList); #ifdef RESOURCE_SCHEDULE_SERVICE_WITH_EXT_RES_ENABLE int32_t GetExtTypeByResPayload(const std::shared_ptr& resData); #endif std::list SortPluginList(const std::list& pluginList); std::string GetStrFromResTypeStrMap(uint32_t resType); class InnerTimeUtil { public: InnerTimeUtil(const std::string& func, const std::string& plugin); ~InnerTimeUtil(); private: TimePoint beginTime_; std::string functionName_; std::string pluginName_; }; // plugin crash 3 times in 60s, will be disable forever const int32_t MAX_PLUGIN_TIMEOUT_TIMES = 3; const int32_t DISABLE_PLUGIN_TIME = 60000; const int32_t DUMP_ONE_STRING_SIZE = 32; int64_t pluginBlockTime = 10 * 60 * 1000 * 1000; std::unique_ptr configReader_ = nullptr; std::unique_ptr pluginSwitch_ = nullptr; std::map pluginLibMap_; // mutex for resTypeMap_ std::mutex resTypeMutex_; // mutex for resTypeLibSyncMap_ std::mutex resTypeSyncMutex_; // mutex for resTypeStrMap_ std::mutex resTypeStrMutex_; std::mutex pluginMutex_; ffrt::mutex dispatcherHandlerMutex_; std::mutex libPathMutex_; std::map> resTypeLibMap_; std::map resTypeLibSyncMap_; std::map resTypeStrMap_; #ifdef RESOURCE_SCHEDULE_SERVICE_WITH_FFRT_ENABLE std::map> dispatchers_; ffrt::mutex runningStatsMutex_; std::map runningStats_; std::unordered_set disablePlugins_; #else std::shared_ptr dispatcher_ = nullptr; #endif std::atomic isInit = {false}; std::map pluginStat_; GetExtMultiConfigFunc getExtMultiConfigFunc_ = nullptr; }; } // namespace ResourceSchedule } // namespace OHOS #endif // RESSCHED_SERVICES_RESSCHEDMGR_RESSCHEDFWK_INCLUDE_PLUGIN_MGR_H