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