1 /*
2  * Copyright (c) 2021-2023 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_H
16 #define HIVIEW_BASE_PLUGIN_H
17 
18 #include <atomic>
19 #include <ctime>
20 #include <memory>
21 #include <string>
22 #include <vector>
23 
24 #include "defines.h"
25 #include "dynamic_module.h"
26 #include "event.h"
27 #include "event_loop.h"
28 
29 class HiEvent;
30 namespace OHOS {
31 namespace HiviewDFX {
32 class HiviewContext;
33 class DllExport Plugin : public EventHandler, public std::enable_shared_from_this<Plugin> {
34 public:
35     enum class PluginType {
36         STATIC,
37         DYNAMIC,
38         PROXY,
39     };
40 public:
Plugin()41     Plugin() : handle_(DynamicModuleDefault), context_(nullptr), useCount_(0) {};
42     virtual ~Plugin();
43     // do not store the event in the callback
44     // create a new one through copy constructor is preferred
45     virtual bool OnEvent(std::shared_ptr<Event>& event) override;
46 
47     /* If the plugin is at the top of a pipeline, this function will be used to determine
48      * whether the current event can be processed by the pipeline.
49      */
50     virtual bool CanProcessEvent(std::shared_ptr<Event> event) override;
51 
52     /* If the plugin is in a pipeline, this function will be used to determine
53      * whether the current pipeline event can be processed by the plugin.
54      */
55     virtual bool IsInterestedPipelineEvent(std::shared_ptr<Event> event) override;
56     virtual bool CanProcessMoreEvents() override;
57     bool OnEventProxy(std::shared_ptr<Event> event) override;
58     virtual std::string GetHandlerInfo() override;
59 
60     // check whether the plugin should be loaded in current environment
61     // the plugin will not be load if return false
62     // called by plugin framework in main thread
ReadyToLoad()63     virtual bool ReadyToLoad()
64     {
65         return true;
66     };
67 
68     // the plugin instance will be stored in platform after calling this function
69     // and other loaded plugin can pass event to this plugin
70     // called by plugin framework in main thread
OnLoad()71     virtual void OnLoad(){};
72 
73     // called by parameter upgrade module
OnConfigUpdate(const std::string & localCfgPath,const std::string & cloudCfgPath)74     virtual void OnConfigUpdate(const std::string &localCfgPath, const std::string &cloudCfgPath) {};
75 
76     // release resource and clear pending workloads
77     // after calling this function ,the reference of this plugin will be deleted
78     // called by plugin framework in main thread
OnUnload()79     virtual void OnUnload(){};
80 
81     // dump plugin info from dump command line
Dump(int fd __UNUSED,const std::vector<std::string> & cmds __UNUSED)82     virtual void Dump(int fd __UNUSED, const std::vector<std::string>& cmds __UNUSED) {};
83 
84     // create an event with specific type
GetEvent(Event::MessageType type)85     virtual std::shared_ptr<Event> GetEvent(Event::MessageType type)
86     {
87         auto event = std::make_shared<Event>(name_);
88         event->messageType_ = type;
89         return event;
90     };
91 
92     // called by audit module
93     virtual std::string GetPluginInfo();
94 
95     // Listener callback
OnEventListeningCallback(const Event & msg)96     virtual void OnEventListeningCallback(const Event &msg)
97     {
98         return;
99     }
100 
101     void AddDispatchInfo(const std::unordered_set<uint8_t>& types,
102         const std::unordered_set<std::string> &eventNames = {}, const std::unordered_set<std::string> &tags = {},
103             const std::unordered_map<std::string, DomainRule>& domainRulesMap = {});
104 
105     // reinsert the event into the workloop
106     // delay in seconds
107     void DelayProcessEvent(std::shared_ptr<Event> event, uint64_t delay);
108 
109     const std::string& GetName();
110     const std::string& GetVersion();
111     void SetName(const std::string& name);
112     void SetVersion(const std::string& version);
113     void BindWorkLoop(std::shared_ptr<EventLoop> loop);
114     void UpdateActiveTime();
115     void UpdateTimeByDelay(time_t delay);
116     std::shared_ptr<EventLoop> GetWorkLoop();
117 
GetHiviewContext()118     HiviewContext* GetHiviewContext()
119     {
120         return context_;
121     };
122 
SetHiviewContext(HiviewContext * context)123     void SetHiviewContext(HiviewContext* context)
124     {
125         std::call_once(contextSetFlag_, [&]() { context_ = context; });
126     };
127 
SetHandle(DynamicModule handle)128     void SetHandle(DynamicModule handle)
129     {
130         handle_ = handle;
131         if (handle_ != nullptr) {
132             type_ = PluginType::DYNAMIC;
133         }
134     };
135 
SetBundleName(const std::string & bundle)136     void SetBundleName(const std::string& bundle)
137     {
138         bundle_ = bundle;
139     }
140 
IsBundlePlugin()141     bool IsBundlePlugin()
142     {
143         return !bundle_.empty();
144     }
145 
HasLoaded()146     bool HasLoaded()
147     {
148         return loaded_;
149     }
150 
SetType(PluginType type)151     void SetType(PluginType type)
152     {
153         type_ = type;
154     }
155 
GetType()156     PluginType GetType() const
157     {
158         return type_;
159     }
160 
GetLastActiveTime()161     time_t GetLastActiveTime() const
162     {
163         return lastActiveTime_;
164     }
165 
GetUseCount()166     int64_t GetUseCount() const
167     {
168         return useCount_;
169     }
170 
AddUseCount()171     void AddUseCount()
172     {
173         ++useCount_;
174     }
175 
SubUseCount()176     void SubUseCount()
177     {
178         --useCount_;
179     }
180 protected:
181     std::string name_;
182     std::string bundle_;
183     std::string version_;
184     std::shared_ptr<EventLoop> workLoop_;
185     PluginType type_ = PluginType::STATIC;
186     std::atomic<time_t> lastActiveTime_;
187 
188 private:
189     DynamicModule handle_;
190     // the reference of the plugin platform
191     // always available in framework callbacks
192     HiviewContext* context_;
193     std::once_flag contextSetFlag_;
194     std::atomic<bool> loaded_;
195     std::atomic<int64_t> useCount_;
196 };
197 class HiviewContext {
198 public:
~HiviewContext()199     virtual ~HiviewContext(){};
200     // post event to broadcast queue, the event will be delivered to all plugin that concern this event
PostUnorderedEvent(std::shared_ptr<Plugin> plugin __UNUSED,std::shared_ptr<Event> event __UNUSED)201     virtual void PostUnorderedEvent(std::shared_ptr<Plugin> plugin __UNUSED, std::shared_ptr<Event> event __UNUSED) {};
202 
203     // register listener to unordered broadcast queue
RegisterUnorderedEventListener(std::weak_ptr<EventListener> listener __UNUSED)204     virtual void RegisterUnorderedEventListener(std::weak_ptr<EventListener> listener __UNUSED) {};
205 
206     // send a event to a specific plugin and wait the return of the OnEvent.
PostSyncEventToTarget(std::shared_ptr<Plugin> caller __UNUSED,const std::string & callee __UNUSED,std::shared_ptr<Event> event __UNUSED)207     virtual bool PostSyncEventToTarget(std::shared_ptr<Plugin> caller __UNUSED, const std::string& callee __UNUSED,
208                                        std::shared_ptr<Event> event __UNUSED)
209     {
210         return true;
211     }
212 
213     // send a event to a specific plugin and return at once
PostAsyncEventToTarget(std::shared_ptr<Plugin> caller __UNUSED,const std::string & callee __UNUSED,std::shared_ptr<Event> event __UNUSED)214     virtual void PostAsyncEventToTarget(std::shared_ptr<Plugin> caller __UNUSED, const std::string& callee __UNUSED,
215                                         std::shared_ptr<Event> event __UNUSED) {};
216 
217     // request plugin platform to release plugin instance
218     // do not recommend unload an plugin in pipeline scheme
219     // platform will check the reference count if other module still holding the reference of this module
RequestUnloadPlugin(std::shared_ptr<Plugin> caller __UNUSED)220     virtual void RequestUnloadPlugin(std::shared_ptr<Plugin> caller __UNUSED) {};
221 
222     // get the shared event loop reference
GetSharedWorkLoop()223     virtual std::shared_ptr<EventLoop> GetSharedWorkLoop()
224     {
225         return nullptr;
226     }
227 
228     // get predefined pipeline list
GetPipelineSequenceByName(const std::string & name __UNUSED)229     virtual std::list<std::weak_ptr<Plugin>> GetPipelineSequenceByName(const std::string& name __UNUSED)
230     {
231         return std::list<std::weak_ptr<Plugin>>(0);
232     }
233 
234     // check if all non-pending loaded plugins are loaded
IsReady()235     virtual bool IsReady()
236     {
237         return false;
238     }
239 
240     enum class DirectoryType {
241         CONFIG_DIRECTORY,
242         WORK_DIRECTORY,
243         PERSIST_DIR,
244     };
245     // get hiview available directory
GetHiViewDirectory(DirectoryType type __UNUSED)246     virtual std::string GetHiViewDirectory(DirectoryType type __UNUSED)
247     {
248         return "";
249     }
GetHiviewProperty(const std::string & key __UNUSED,const std::string & defaultValue)250     virtual std::string GetHiviewProperty(const std::string& key __UNUSED, const std::string& defaultValue)
251     {
252         return defaultValue;
253     }
254 
SetHiviewProperty(const std::string & key __UNUSED,const std::string & value __UNUSED,bool forceUpdate __UNUSED)255     virtual bool SetHiviewProperty(const std::string& key __UNUSED, const std::string& value __UNUSED,
256         bool forceUpdate __UNUSED)
257     {
258         return true;
259     }
260 
AppendPluginToPipeline(const std::string & pluginName __UNUSED,const std::string & pipelineName __UNUSED)261     virtual void AppendPluginToPipeline(const std::string& pluginName __UNUSED,
262                                         const std::string& pipelineName __UNUSED) {};
RequestLoadBundle(const std::string & bundleName __UNUSED)263     virtual void RequestLoadBundle(const std::string& bundleName __UNUSED) {};
264 
265     // request plugin platform to release plugin bundle
266     virtual void RequestUnloadBundle(const std::string& bundleName, uint64_t delay = 0) {};
267 
InstancePluginByProxy(std::shared_ptr<Plugin> proxy __UNUSED)268     virtual std::shared_ptr<Plugin> InstancePluginByProxy(std::shared_ptr<Plugin> proxy __UNUSED)
269     {
270         return nullptr;
271     }
272 
GetPluginByName(const std::string & name)273     virtual std::shared_ptr<Plugin> GetPluginByName(const std::string& name)
274     {
275         return nullptr;
276     }
277 
AddListenerInfo(uint32_t type,const std::string & name,const std::set<std::string> & eventNames,const std::map<std::string,DomainRule> & domainRulesMap)278     virtual void AddListenerInfo(uint32_t type, const std::string& name, const std::set<std::string>& eventNames,
279         const std::map<std::string, DomainRule>& domainRulesMap) {};
280 
AddListenerInfo(uint32_t type,const std::string & name)281     virtual void AddListenerInfo(uint32_t type, const std::string& name) {};
282 
GetListenerInfo(uint32_t type,const std::string & eventName,const std::string & domain)283     virtual std::vector<std::weak_ptr<EventListener>> GetListenerInfo(uint32_t type,
284         const std::string& eventName, const std::string& domain)
285     {
286         return {};
287     }
288 
AddDispatchInfo(std::weak_ptr<Plugin> plugin,const std::unordered_set<uint8_t> & types,const std::unordered_set<std::string> & eventNames,const std::unordered_set<std::string> & tags,const std::unordered_map<std::string,DomainRule> & domainRulesMap)289     virtual void AddDispatchInfo(std::weak_ptr<Plugin> plugin, const std::unordered_set<uint8_t>& types,
290         const std::unordered_set<std::string>& eventNames, const std::unordered_set<std::string>& tags,
291             const std::unordered_map<std::string, DomainRule>& domainRulesMap) {};
292 
GetDisPatcherInfo(uint32_t type,const std::string & eventName,const std::string & tag,const std::string & domain)293     virtual std::vector<std::weak_ptr<Plugin>> GetDisPatcherInfo(uint32_t type,
294         const std::string& eventName, const std::string& tag, const std::string& domain)
295     {
296         return {};
297     }
298 };
299 } // namespace HiviewDFX
300 } // namespace OHOS
301 #endif // HIVIEW_BASE_PLUGIN_H
302