MythTV master
mythplugin.cpp
Go to the documentation of this file.
1#include <QtGlobal>
2#if QT_VERSION >= QT_VERSION_CHECK(6,0,0)
3#include <QtSystemDetection>
4#endif
5
6// C includes
7#ifndef Q_OS_WINDOWS
8#include <dlfcn.h>
9#else
10#include "compat.h"
11#endif
12
13// Qt includes
14#include <QDir>
15
16// MythTV includes
17
18// libmythbase
19#include "mythplugin.h"
20#include "mythcorecontext.h"
21#include "mythtranslation.h"
22#include "mythdirs.h"
23#include "mythversion.h"
24#include "mythlogging.h"
25
26int MythPlugin::init(const char *libversion)
27{
28 using PluginInitFunc = int (*)(const char *);
29 auto ifunc = (PluginInitFunc)QLibrary::resolve("mythplugin_init");
30 if (ifunc)
31 return ifunc(libversion);
32
33 QString error_msg(dlerror());
34 if (error_msg.isEmpty())
35 {
36 QByteArray libname = QLibrary::fileName().toLatin1();
37 (void)dlopen(libname.constData(), RTLD_LAZY);
38 error_msg = dlerror();
39 }
40
41 LOG(VB_GENERAL, LOG_EMERG, QString("MythPlugin::init() dlerror: %1")
42 .arg(error_msg));
43
44 return -1;
45}
46
48{
49 using PluginRunFunc = int (*)();
50
51 int rVal = -1;
52 auto rfunc = (PluginRunFunc)QLibrary::resolve("mythplugin_run");
53
54 if (rfunc)
55 rVal = rfunc();
56
57 return rVal;
58}
59
61{
62 using PluginConfigFunc = int (*)();
63
64 int rVal = -1;
65 auto rfunc = (PluginConfigFunc)QLibrary::resolve("mythplugin_config");
66
67 if (rfunc)
68 {
69 rVal = rfunc();
71 }
72
73 return rVal;
74}
75
77{
78 using PluginTypeFunc = MythPluginType (*)();
79 auto rfunc = (PluginTypeFunc)QLibrary::resolve("mythplugin_type");
80
81 if (rfunc)
82 return rfunc();
83
84 return kPluginType_Module;
85}
86
88{
89 using PluginDestFunc = void (*)();
90 PluginDestFunc rfunc = QLibrary::resolve("mythplugin_destroy");
91
92 if (rfunc)
93 rfunc();
94}
95
97{
98 QString pluginprefix = GetPluginsDir();
99
100 QDir filterDir(pluginprefix);
101
102 filterDir.setFilter(QDir::Files | QDir::Readable);
103 QString filter = GetPluginsNameFilter();
104 filterDir.setNameFilters(QStringList(filter));
105
106 if (filterDir.exists())
107 {
108 int prefixLength = filter.indexOf("*");
109 int suffixLength = filter.length() - prefixLength - 1;
110
111 QStringList libraries = filterDir.entryList();
112 if (libraries.isEmpty())
113 LOG(VB_GENERAL, LOG_WARNING,
114 "No libraries in plugins directory " + filterDir.path());
115
116 // coverity[auto_causes_copy]
117 for (auto library : std::as_const(libraries))
118 {
119 // pull out the base library name
120 library = library.right(library.length() - prefixLength);
121 library = library.left(library.length() - suffixLength);
122
123 init_plugin(library);
124 }
125 }
126 else
127 {
128 LOG(VB_GENERAL, LOG_WARNING,
129 "No plugins directory " + filterDir.path());
130 }
131}
132
133bool MythPluginManager::init_plugin(const QString &plugname)
134{
135 QString newname = FindPluginName(plugname);
136
137 if (!m_dict[newname])
138 {
139 m_dict.insert(newname, new MythPlugin(newname, plugname));
140 }
141
142 int result = m_dict[newname]->init(MYTH_BINARY_VERSION);
143
144 if (result == -1)
145 {
146 delete m_dict[newname];
147 m_dict.remove(newname);
148 LOG(VB_GENERAL, LOG_ERR,
149 QString("Unable to initialize plugin '%1'.") .arg(plugname));
150 return false;
151 }
152
153 MythTranslation::load(plugname);
154
155 switch (m_dict[newname]->type())
156 {
158 default:
159 m_moduleMap[newname] = m_dict[newname];
160 break;
161 }
162
163 return true;
164}
165
166// return false on success, true on error
167bool MythPluginManager::run_plugin(const QString &plugname)
168{
169 QString newname = FindPluginName(plugname);
170
171 if (!m_dict[newname] && !init_plugin(plugname))
172 {
173 LOG(VB_GENERAL, LOG_ALERT,
174 QString("Unable to run plugin '%1': not initialized")
175 .arg(plugname));
176 return true;
177 }
178
179 bool res = m_dict[newname]->run() != 0;
180
181 return res;
182}
183
184// return false on success, true on error
185bool MythPluginManager::config_plugin(const QString &plugname)
186{
187 QString newname = FindPluginName(plugname);
188
189 if (!m_dict[newname] && !init_plugin(plugname))
190 {
191 LOG(VB_GENERAL, LOG_ALERT,
192 QString("Unable to configure plugin '%1': not initialized")
193 .arg(plugname));
194 return true;
195 }
196
197 bool res = m_dict[newname]->config() != 0;
198
199 return res;
200}
201
202bool MythPluginManager::destroy_plugin(const QString &plugname)
203{
204 QString newname = FindPluginName(plugname);
205
206 if (!m_dict[newname] && !init_plugin(plugname))
207 {
208 LOG(VB_GENERAL, LOG_ALERT,
209 QString("Unable to destroy plugin '%1': not initialized")
210 .arg(plugname));
211 return false;
212 }
213
214 m_dict[newname]->destroy();
215 return true;
216}
217
219{
220 QString newname = FindPluginName(plugname);
221
222 if (!m_moduleMap.contains(newname))
223 return nullptr;
224
225 return m_moduleMap[newname];
226}
227
229{
230 for (auto *it : std::as_const(m_dict))
231 {
232 it->destroy();
233 delete it;
234 }
235
236 m_dict.clear();
237 m_moduleMap.clear();
238}
239
241{
242 QStringList ret;
243 for (auto *it : std::as_const(m_dict))
244 ret << it->getName();
245 return ret;
246}
void ClearSettingsCache(const QString &myKey=QString(""))
bool init_plugin(const QString &plugname)
Definition: mythplugin.cpp:133
bool config_plugin(const QString &plugname)
Definition: mythplugin.cpp:185
void DestroyAllPlugins()
Definition: mythplugin.cpp:228
QMap< QString, MythPlugin * > m_moduleMap
Definition: mythplugin.h:81
bool destroy_plugin(const QString &plugname)
Definition: mythplugin.cpp:202
MythPlugin * GetPlugin(const QString &plugname)
Definition: mythplugin.cpp:218
bool run_plugin(const QString &plugname)
Definition: mythplugin.cpp:167
QStringList EnumeratePlugins(void)
Definition: mythplugin.cpp:240
QHash< QString, MythPlugin * > m_dict
Definition: mythplugin.h:79
int init(const char *libversion)
Definition: mythplugin.cpp:26
void destroy(void)
Definition: mythplugin.cpp:87
MythPluginType type(void)
Definition: mythplugin.cpp:76
int config(void)
Definition: mythplugin.cpp:60
int run(void)
Definition: mythplugin.cpp:47
static void load(const QString &module_name)
Load a QTranslator for the user's preferred language.
#define RTLD_LAZY
Definition: compat.h:105
#define dlopen(x, y)
Definition: compat.h:106
const char * dlerror(void)
Definition: compat.h:111
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
QString GetPluginsNameFilter(void)
Definition: mythdirs.cpp:349
QString FindPluginName(const QString &plugname)
Definition: mythdirs.cpp:354
QString GetPluginsDir(void)
Definition: mythdirs.cpp:287
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:39
MythPluginType
Definition: mythplugin.h:18
@ kPluginType_Module
Definition: mythplugin.h:19