1 /* 2 * Copyright (c) 2021-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 #ifndef HIVIEW_BASE_PLUGIN_PLATFORM_H 16 #define HIVIEW_BASE_PLUGIN_PLATFORM_H 17 #include <memory> 18 #include <mutex> 19 #include <string> 20 21 #include "defines.h" 22 #include "dynamic_module.h" 23 #include "event_dispatch_queue.h" 24 #include "event_loop.h" 25 #include "event_source.h" 26 #include "pipeline.h" 27 #include "plugin.h" 28 #include "plugin_bundle.h" 29 #include "plugin_config.h" 30 #include "singleton.h" 31 32 namespace OHOS { 33 namespace HiviewDFX { 34 using PipelineConfigMap = std::map<std::string, std::shared_ptr<DispatchRule>>; 35 class HiviewPlatform : public HiviewContext, public Singleton<HiviewPlatform> { 36 public: 37 HiviewPlatform(); 38 ~HiviewPlatform(); 39 bool InitEnvironment(const std::string& platformConfigDir = ""); 40 void ProcessArgsRequest(int argc, char* argv[]); 41 void StartLoop(); 42 void SetMaxProxyIdleTime(time_t idleTime); 43 void SetCheckProxyIdlePeriod(time_t period); 44 45 void PostUnorderedEvent(std::shared_ptr<Plugin> plugin, std::shared_ptr<Event> event) override; 46 void RegisterUnorderedEventListener(std::weak_ptr<EventListener> listener) override; 47 bool PostSyncEventToTarget(std::shared_ptr<Plugin> caller, const std::string& calleeName, 48 std::shared_ptr<Event> event) override; 49 void PostAsyncEventToTarget(std::shared_ptr<Plugin> caller, const std::string& calleeName, 50 std::shared_ptr<Event> event) override; 51 void RequestUnloadPlugin(std::shared_ptr<Plugin> caller) override; 52 std::list<std::weak_ptr<Plugin>> GetPipelineSequenceByName(const std::string& name) override; 53 std::shared_ptr<EventLoop> GetSharedWorkLoop() override; 54 std::shared_ptr<EventLoop> GetMainWorkLoop() override; 55 std::string GetHiViewDirectory(DirectoryType type) override; 56 std::string GetHiviewProperty(const std::string& key, const std::string& defaultValue) override; 57 bool SetHiviewProperty(const std::string& key, const std::string& value, bool forceUpdate) override; 58 bool IsReady() override; 59 void AppendPluginToPipeline(const std::string& pluginName, const std::string& pipelineName) override; 60 void RequestLoadBundle(const std::string& bundleName __UNUSED) override; 61 void RequestUnloadBundle(const std::string& bundleName, uint64_t delay = 0) override; 62 std::shared_ptr<Plugin> InstancePluginByProxy(std::shared_ptr<Plugin> proxy) override; 63 std::shared_ptr<Plugin> GetPluginByName(const std::string& name) override; 64 void AddDispatchInfo(std::weak_ptr<Plugin> plugin, const std::unordered_set<uint8_t>& types, 65 const std::unordered_set<std::string>& eventNames, const std::unordered_set<std::string>& tags, 66 const std::unordered_map<std::string, DomainRule>& domainRulesMap) override; 67 std::vector<std::weak_ptr<Plugin>> GetDisPatcherInfo(uint32_t type, 68 const std::string& eventName, const std::string& tag, const std::string& domain) override; 69 void AddListenerInfo(uint32_t type, const std::string& name, const std::set<std::string>& eventNames, 70 const std::map<std::string, DomainRule>& domainRulesMap) override; 71 void AddListenerInfo(uint32_t type, const std::string& name) override; 72 std::vector<std::weak_ptr<EventListener>> GetListenerInfo(uint32_t type, 73 const std::string& eventName, const std::string& domain) override; 74 GetPipelineConfigMap()75 PipelineConfigMap& GetPipelineConfigMap() 76 { 77 return pipelineRules_; 78 } 79 GetPluginMap()80 const std::map<std::string, std::shared_ptr<Plugin>>& GetPluginMap() 81 { 82 return pluginMap_; 83 } 84 GetPipelineMap()85 const std::map<std::string, std::shared_ptr<Pipeline>>& GetPipelineMap() 86 { 87 return pipelines_; 88 } 89 GetWorkLoopMap()90 const std::map<std::string, std::shared_ptr<EventLoop>>& GetWorkLoopMap() 91 { 92 return privateWorkLoopMap_; 93 } 94 GetPluginBundleInfoMap()95 const std::map<std::string, std::shared_ptr<PluginBundle>>& GetPluginBundleInfoMap() 96 { 97 return pluginBundleInfos_; 98 } 99 100 private: 101 struct ListenerInfo { 102 std::weak_ptr<EventListener> listener_; 103 std::vector<uint32_t> messageTypes_; 104 std::map<uint32_t, std::set<std::string>> eventsInfo_; 105 std::map<uint32_t, std::map<std::string, DomainRule>> domainsInfo_; MatchListenerInfo106 bool Match(uint32_t type, const std::string& eventName, const std::string& domain) 107 { 108 auto it = std::find(messageTypes_.begin(), messageTypes_.end(), type); 109 if (it != messageTypes_.end()) { 110 return true; 111 } 112 auto itEventList = eventsInfo_.find(type); 113 if (itEventList != eventsInfo_.end()) { 114 auto eventList = itEventList->second; 115 if (eventList.find(eventName) != eventList.end()) { 116 return true; 117 } 118 } 119 auto itDomainsInfo = domainsInfo_.find(type); 120 if (itDomainsInfo != domainsInfo_.end()) { 121 auto itDomainRule = itDomainsInfo->second.find(domain); 122 if (itDomainRule != itDomainsInfo->second.end()) { 123 return itDomainRule->second.FindEvent(eventName); 124 } 125 } 126 return false; 127 } 128 }; 129 130 struct DispatchInfo { 131 std::weak_ptr<Plugin> plugin_; 132 std::unordered_set<uint8_t> typesInfo_; 133 std::unordered_set<std::string> eventsInfo_; 134 std::unordered_set<std::string> tagsInfo_; 135 std::unordered_map<std::string, DomainRule> domainsInfo_; MatchDispatchInfo136 bool Match(uint8_t type, const std::string& eventName, const std::string& tag, 137 const std::string& domain) 138 { 139 if (typesInfo_.find(type) != typesInfo_.end()) { 140 return true; 141 } 142 if (tagsInfo_.find(tag) != tagsInfo_.end()) { 143 return true; 144 } 145 if (eventsInfo_.find(eventName) != eventsInfo_.end()) { 146 return true; 147 } 148 auto itDomainRule = domainsInfo_.find(domain); 149 if (itDomainRule != domainsInfo_.end()) { 150 return itDomainRule->second.FindEvent(eventName); 151 } 152 return false; 153 } 154 }; 155 156 void CreateWorkingDirectories(const std::string& platformConfigDir); 157 void StartPlatformDispatchQueue(); 158 void CreatePlugin(const PluginConfig::PluginInfo& pluginInfo); 159 void CreatePipeline(const PluginConfig::PipelineInfo& pipelineInfo); 160 void InitPlugin(const PluginConfig& config __UNUSED, const PluginConfig::PluginInfo& pluginInfo); 161 void NotifyPluginReady(); 162 void ScheduleCreateAndInitPlugin(const PluginConfig::PluginInfo& pluginInfo); 163 DynamicModule LoadDynamicPlugin(const std::string& name) const; 164 std::string GetDynamicLibName(const std::string& name, bool hasOhosSuffix) const; 165 std::shared_ptr<EventLoop> GetAvailableWorkLoop(const std::string& name); 166 void CleanupUnusedResources(); 167 void UnloadPlugin(const std::string& name); 168 void StartEventSource(std::shared_ptr<EventSource> source); 169 void ValidateAndCreateDirectory(std::string& defaultPath, const std::string& realPath); 170 void ValidateAndCreateDirectories(const std::string& localPath, const std::string& workPath, 171 const std::string& persistPath); 172 void LoadBusinessPlugin(const PluginConfig& config); 173 void ExitHiviewIfNeed(); 174 std::string GetPluginConfigPath(); 175 std::string SplitBundleNameFromPath(const std::string& filePath); 176 void UpdateBetaConfigIfNeed(); 177 void LoadPluginBundles(); 178 void LoadPluginBundle(const std::string& bundleName, const std::string& filePath); 179 void ScheduleCheckUnloadablePlugins(); 180 void CheckUnloadablePlugins(); 181 std::string SearchPluginBundle(const std::string& name) const; 182 183 bool isReady_; 184 std::string defaultConfigDir_; 185 std::string defaultWorkDir_; 186 std::string defaultCommercialWorkDir_; 187 std::string defaultPersistDir_; 188 std::string defaultConfigName_; 189 std::vector<std::string> dynamicLibSearchDir_; 190 std::shared_ptr<EventDispatchQueue> unorderQueue_; 191 std::shared_ptr<EventLoop> sharedWorkLoop_; 192 std::shared_ptr<EventLoop> mainWorkLoop_; 193 std::map<std::string, std::shared_ptr<Plugin>> pluginMap_; 194 std::map<std::string, std::shared_ptr<Pipeline>> pipelines_; 195 std::map<std::string, std::shared_ptr<EventLoop>> privateWorkLoopMap_; 196 std::map<std::string, std::string> hiviewProperty_; 197 std::map<std::string, std::shared_ptr<PluginBundle>> pluginBundleInfos_; 198 199 // Listener data structure:<pluginName, <domain_eventName, Plugin>> 200 std::unordered_map<std::string, std::shared_ptr<ListenerInfo>> listeners_; 201 std::unordered_map<std::string, std::shared_ptr<DispatchInfo>> dispatchers_; 202 PipelineConfigMap pipelineRules_; 203 std::vector<std::shared_ptr<Plugin>> eventSourceList_; 204 205 // the max waited time before destroy plugin instance 206 const time_t DEFAULT_IDLE_TIME = 300; // 300 seconds 207 time_t maxIdleTime_ = DEFAULT_IDLE_TIME; 208 time_t checkIdlePeriod_ = DEFAULT_IDLE_TIME / 2; // 2 : half idle time 209 }; 210 } // namespace HiviewDFX 211 } // namespace OHOS 212 #endif // HIVIEW_BASE_PLUGIN_PLATFORM_H 213