Files

302 lines
8.8 KiB
C++
Raw Permalink Normal View History

2020-07-30 17:59:34 +08:00
/* -*- Mode: C++; indent-tabs-mode: nil; tab-width: 4 -*-
* -*- coding: utf-8 -*-
*
* Copyright (C) 2020 KylinSoft Co., Ltd.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
2020-03-09 15:04:02 +08:00
#include "plugin-info.h"
2020-03-04 17:56:39 +08:00
#include "global.h"
2020-03-09 15:04:02 +08:00
#include "clib-syslog.h"
2020-03-03 18:47:54 +08:00
2020-03-09 22:14:25 -07:00
#include <QDebug>
2020-03-14 20:14:30 -07:00
#include <QFile>
2020-03-09 22:14:25 -07:00
2020-03-09 15:04:02 +08:00
PluginInfo::PluginInfo(QString& fileName)
2020-03-03 18:47:54 +08:00
{
int priority;
2020-03-14 20:14:30 -07:00
char* str = NULL;
2020-03-05 18:41:01 +08:00
GError* error = NULL;
2020-03-14 20:14:30 -07:00
GKeyFile* pluginFile = NULL;
2020-03-03 18:47:54 +08:00
2020-03-06 15:23:45 +08:00
mPriority = 0;
mActive = false;
mEnabled = true;
mPlugin = nullptr;
mModule = nullptr;
mAvailable = true;
mSettings = nullptr;
QByteArray* bt = new QByteArray(fileName.toUtf8().data());
mFile = *bt;
2020-03-03 18:47:54 +08:00
pluginFile = g_key_file_new();
2020-03-06 15:23:45 +08:00
if (!g_key_file_load_from_file(pluginFile, (char*)fileName.toUtf8().data(), G_KEY_FILE_NONE, &error)) {
2020-03-14 20:14:30 -07:00
CT_SYSLOG(LOG_ERR, "Bad plugin file:'%s', error:'%s'", fileName.toUtf8().data(), error->message);
2020-03-06 15:23:45 +08:00
g_object_unref(error);
2020-03-14 20:14:30 -07:00
error = nullptr;
g_object_unref(pluginFile);
return;
2020-03-03 18:47:54 +08:00
}
2020-03-06 15:23:45 +08:00
if (!g_key_file_has_key(pluginFile, PLUGIN_GROUP, "IAge", &error)) {
2020-03-14 20:14:30 -07:00
CT_SYSLOG(LOG_ERR, "IAge key does not exist in file: %s, error: '%s'", fileName.toUtf8().data(), error->message);
2020-03-06 15:23:45 +08:00
g_object_unref(error);
2020-03-14 20:14:30 -07:00
error = nullptr;
2020-03-03 18:47:54 +08:00
}
/* Check IAge=2 */
2020-03-06 15:23:45 +08:00
if (g_key_file_get_integer (pluginFile, PLUGIN_GROUP, "IAge", &error) != 0) {
2020-03-14 20:14:30 -07:00
CT_SYSLOG(LOG_ERR, "Wrong IAge in file: %s, error: '%s'", fileName.toUtf8().data(), error->message);
2020-03-06 15:23:45 +08:00
g_object_unref(error);
2020-03-14 20:14:30 -07:00
error = nullptr;
2020-03-03 18:47:54 +08:00
}
/* Get Location */
2020-03-06 15:23:45 +08:00
str = g_key_file_get_string (pluginFile, PLUGIN_GROUP, "Module", &error);
2020-03-03 18:47:54 +08:00
if ((str != NULL) && (*str != '\0')) {
2020-03-06 15:23:45 +08:00
mLocation = str;
2020-03-03 18:47:54 +08:00
} else {
g_free (str);
2020-03-14 20:14:30 -07:00
CT_SYSLOG(LOG_ERR, "Could not find 'Module' in %s, error: '%s'", fileName.toUtf8().data(), error->message);
2020-03-06 15:23:45 +08:00
g_object_unref(error);
2020-03-14 20:14:30 -07:00
error = nullptr;
2020-03-03 18:47:54 +08:00
}
/* Get Name */
2020-03-14 20:14:30 -07:00
str = g_key_file_get_locale_string (pluginFile, PLUGIN_GROUP, "Name", NULL, &error);
2020-03-03 18:47:54 +08:00
if (str != NULL) {
2020-03-09 23:38:34 -07:00
mName = str;
2020-03-03 18:47:54 +08:00
} else {
2020-03-14 20:14:30 -07:00
CT_SYSLOG(LOG_ERR, "Could not find %s, error '%s'", fileName.toUtf8().data(), error->message);
2020-03-06 15:23:45 +08:00
g_object_unref(error);
2020-03-14 20:14:30 -07:00
error = nullptr;
2020-03-03 18:47:54 +08:00
}
/* Get Description */
2020-03-14 20:14:30 -07:00
str = g_key_file_get_locale_string (pluginFile, PLUGIN_GROUP, "Description", NULL, &error);
2020-03-03 18:47:54 +08:00
if (str != NULL) {
2020-03-06 15:23:45 +08:00
mDesc = QString(str);
2020-03-03 18:47:54 +08:00
} else {
2020-03-14 20:14:30 -07:00
CT_SYSLOG(LOG_ERR, "Could not find 'Description' in %s, error: '%s'", fileName.toUtf8().data(), error->message);
g_object_unref(error);
error = nullptr;
2020-03-03 18:47:54 +08:00
}
/* Get Authors */
2020-03-14 20:14:30 -07:00
mAuthors = new QList<QString>();
char** author = g_key_file_get_string_list (pluginFile, PLUGIN_GROUP, "Authors", NULL, &error);
if (nullptr != author) {
for (int i = 0; author[i] != NULL; ++i) mAuthors->append(author[i]);
} else {
CT_SYSLOG(LOG_ERR, "Could not find 'Authors' in %s, error: '%s'", fileName.toUtf8().data(), error->message);
g_object_unref(error);
error = nullptr;
2020-03-03 18:47:54 +08:00
}
2020-03-14 20:14:30 -07:00
g_strfreev (author);
author = nullptr;
2020-03-03 18:47:54 +08:00
/* Get Copyright */
2020-03-14 20:14:30 -07:00
str = g_key_file_get_string (pluginFile, PLUGIN_GROUP, "Copyright", &error);
2020-03-03 18:47:54 +08:00
if (str != NULL) {
2020-03-14 20:14:30 -07:00
mCopyright = str;
2020-03-03 18:47:54 +08:00
} else {
2020-03-14 20:14:30 -07:00
CT_SYSLOG(LOG_ERR, "Could not find 'Copyright' in %s, error: '%s'", fileName.toUtf8().data(), error->message);
g_object_unref(error);
error = nullptr;
2020-03-03 18:47:54 +08:00
}
/* Get Website */
2020-03-14 20:14:30 -07:00
str = g_key_file_get_string (pluginFile, PLUGIN_GROUP, "Website", &error);
2020-03-03 18:47:54 +08:00
if (str != NULL) {
2020-03-14 20:14:30 -07:00
mWebsite = str;
2020-03-03 18:47:54 +08:00
} else {
2020-03-14 20:14:30 -07:00
CT_SYSLOG(LOG_ERR, "Could not find 'Website' in %s, error: '%s'", fileName.toUtf8().data(), error->message);
g_object_unref(error);
error = nullptr;
2020-03-03 18:47:54 +08:00
}
/* Get Priority */
priority = g_key_file_get_integer (pluginFile, PLUGIN_GROUP, "Priority", NULL);
if (priority >= PLUGIN_PRIORITY_MAX) {
2020-03-04 17:56:39 +08:00
this->mPriority = priority;
2020-03-03 18:47:54 +08:00
} else {
2020-03-04 17:56:39 +08:00
this->mPriority = PLUGIN_PRIORITY_DEFAULT;
2020-03-03 18:47:54 +08:00
}
2020-03-14 20:14:30 -07:00
if (nullptr != error) g_object_unref(error);
if (nullptr != pluginFile) g_key_file_free (pluginFile);
}
PluginInfo::~PluginInfo()
{
2020-03-15 19:51:57 -07:00
if (nullptr != mModule) {mModule->unload(); delete mModule; mModule = nullptr;}
2020-03-14 20:14:30 -07:00
if (nullptr != mAuthors) {delete mAuthors; mAuthors = nullptr;}
if (nullptr != mSettings) {delete mSettings; mSettings = nullptr;}
2020-03-03 18:47:54 +08:00
}
2020-03-09 15:04:02 +08:00
bool PluginInfo::pluginActivate()
2020-03-03 18:47:54 +08:00
{
2020-03-14 22:14:16 -07:00
bool res = false;
2020-03-06 15:23:45 +08:00
if (!mAvailable) {CT_SYSLOG(LOG_DEBUG, "plugin is not available!") return false;}
if (mActive) {CT_SYSLOG(LOG_DEBUG, "plugin has activity!") return true;}
2020-03-03 18:47:54 +08:00
2020-03-14 22:14:16 -07:00
// load module
if (nullptr == mPlugin) {
res = loadPluginModule(*this);
2020-03-03 18:47:54 +08:00
}
2020-03-14 22:14:16 -07:00
if (res && (nullptr != mPlugin)) {
mPlugin->activate();
mActive = true;
res = true;
} else {
res = false;
CT_SYSLOG(LOG_ERR, "Error activating plugin '%s'", this->mName.toUtf8().data());
}
return res;
2020-03-03 18:47:54 +08:00
}
2020-03-09 15:04:02 +08:00
bool PluginInfo::pluginDeactivate()
2020-03-03 18:47:54 +08:00
{
2020-03-09 23:38:34 -07:00
if (!mActive || !mAvailable) {
2020-03-14 22:14:16 -07:00
return true;
2020-03-09 23:38:34 -07:00
}
2020-03-03 18:47:54 +08:00
2020-03-14 22:14:16 -07:00
if (nullptr != mPlugin) {
mPlugin->deactivate();
} else {
return false;
}
mActive = false;
return true;
2020-03-03 18:47:54 +08:00
}
2020-03-09 15:04:02 +08:00
bool PluginInfo::pluginIsactivate()
2020-03-03 18:47:54 +08:00
{
2020-03-09 23:38:34 -07:00
return (mAvailable && mActive);
2020-03-03 18:47:54 +08:00
}
2020-03-09 15:04:02 +08:00
bool PluginInfo::pluginEnabled()
2020-03-03 18:47:54 +08:00
{
2020-03-06 15:23:45 +08:00
return (this->mEnabled);
2020-03-03 18:47:54 +08:00
}
2020-03-09 15:04:02 +08:00
bool PluginInfo::pluginIsAvailable()
2020-03-03 18:47:54 +08:00
{
2020-03-14 20:14:30 -07:00
return this->mAvailable;
2020-03-03 18:47:54 +08:00
}
2020-03-09 15:04:02 +08:00
QString& PluginInfo::getPluginName()
2020-03-03 18:47:54 +08:00
{
2020-03-04 17:56:39 +08:00
return this->mName;
2020-03-03 18:47:54 +08:00
}
2020-03-09 15:04:02 +08:00
QString& PluginInfo::getPluginDescription()
2020-03-03 18:47:54 +08:00
{
2020-03-04 17:56:39 +08:00
return this->mDesc;
2020-03-03 18:47:54 +08:00
}
2020-03-14 20:14:30 -07:00
QList<QString>& PluginInfo::getPluginAuthors()
2020-03-03 18:47:54 +08:00
{
2020-03-14 20:14:30 -07:00
return *mAuthors;
2020-03-03 18:47:54 +08:00
}
2020-03-09 15:04:02 +08:00
QString& PluginInfo::getPluginWebsite()
2020-03-03 18:47:54 +08:00
{
2020-03-04 17:56:39 +08:00
return this->mWebsite;
2020-03-03 18:47:54 +08:00
}
2020-03-09 15:04:02 +08:00
QString& PluginInfo::getPluginCopyright()
2020-03-03 18:47:54 +08:00
{
2020-03-04 17:56:39 +08:00
return this->mCopyright;
2020-03-03 18:47:54 +08:00
}
2020-03-09 15:04:02 +08:00
QString& PluginInfo::getPluginLocation()
2020-03-03 18:47:54 +08:00
{
2020-03-04 17:56:39 +08:00
return this->mLocation;
2020-03-03 18:47:54 +08:00
}
2020-03-14 22:14:16 -07:00
int PluginInfo::getPluginPriority()
2020-03-03 18:47:54 +08:00
{
2020-03-04 17:56:39 +08:00
return this->mPriority;
2020-03-03 18:47:54 +08:00
}
2020-03-09 15:04:02 +08:00
void PluginInfo::setPluginPriority(int priority)
2020-03-03 18:47:54 +08:00
{
2020-03-04 17:56:39 +08:00
this->mPriority = priority;
2020-03-03 18:47:54 +08:00
}
2020-03-14 20:14:30 -07:00
// FIXME:// ?????
2020-03-09 15:04:02 +08:00
void PluginInfo::setPluginSchema(QString& schema)
2020-03-03 18:47:54 +08:00
{
int priority;
2020-03-06 15:23:45 +08:00
2020-03-14 20:14:30 -07:00
mSettings = new QGSettings(schema.toUtf8());
this->mEnabled = mSettings->get("active").toBool();
priority = mSettings->get("priority").toInt();
2020-03-04 17:56:39 +08:00
if (priority > 0) this->mPriority = priority;
2020-03-14 20:14:30 -07:00
if (!connect(mSettings, SIGNAL(changed(QString)), this, SLOT(pluginSchemaSlot(QString)))){
CT_SYSLOG(LOG_ERR, "plugin setting '%s', connect error!", schema.toUtf8().data());
}
2020-03-03 18:47:54 +08:00
}
2020-03-09 23:38:34 -07:00
bool PluginInfo::operator==(PluginInfo& oth)
{
return (0 == QString::compare(mName, oth.getPluginName(), Qt::CaseInsensitive));
}
2020-03-14 22:16:42 -07:00
void PluginInfo::pluginSchemaSlot(QString)
2020-03-14 20:14:30 -07:00
{
// if configure has changed, modify PluginInfo
// if configure deactivity plugin, activate() else deactivate()
}
2020-03-14 22:14:16 -07:00
bool loadPluginModule(PluginInfo& pinfo)
2020-03-03 18:47:54 +08:00
{
2020-03-06 15:23:45 +08:00
QString path;
2020-03-03 18:47:54 +08:00
2020-03-14 22:14:16 -07:00
if (pinfo.mFile.isNull() || pinfo.mFile.isEmpty()) {CT_SYSLOG(LOG_ERR, "Plugin file is error"); return false;}
if (pinfo.mLocation.isNull() || pinfo.mLocation.isEmpty()) {CT_SYSLOG(LOG_ERR, "Plugin location is error"); return false;}
if (!pinfo.mAvailable) {CT_SYSLOG(LOG_ERR, "Plugin is not available"); return false;}
2020-03-03 18:47:54 +08:00
2020-03-14 22:14:16 -07:00
QFile file(pinfo.mFile);
2020-03-14 20:14:30 -07:00
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) return false;
2020-03-03 18:47:54 +08:00
2020-03-14 22:14:16 -07:00
QStringList l = pinfo.mFile.split("/");
2020-03-06 15:23:45 +08:00
l.pop_back();
2020-03-14 22:14:16 -07:00
path = l.join("/") + "/lib" + pinfo.mLocation + ".so";
2020-03-04 09:41:40 +08:00
if (path.isEmpty() || path.isNull()) {syslog(LOG_ERR, "error module path:'%s'", path.toUtf8().data()); return false;}
2020-03-03 18:47:54 +08:00
2020-03-14 22:14:16 -07:00
pinfo.mModule = new QLibrary(path);
2020-03-25 10:00:10 +08:00
pinfo.mModule->setLoadHints(QLibrary::ResolveAllSymbolsHint | QLibrary::ExportExternalSymbolsHint);
2020-03-14 22:14:16 -07:00
if (!(pinfo.mModule->load())) {
syslog(LOG_ERR, "create module '%s' error:'%s'", path.toUtf8().data(), pinfo.mModule->errorString().toUtf8().data());
2020-03-14 22:14:16 -07:00
pinfo.mAvailable = false;
2020-03-06 15:23:45 +08:00
return false;
2020-03-03 18:47:54 +08:00
}
2020-03-09 15:04:02 +08:00
typedef PluginInterface* (*createPlugin) ();
2020-03-14 22:14:16 -07:00
createPlugin p = (createPlugin)pinfo.mModule->resolve("createSettingsPlugin");
2020-03-06 15:23:45 +08:00
if (!p) {
syslog(LOG_ERR, "create module class failed, error: '%s'", pinfo.mModule->errorString().toUtf8().data());
2020-03-06 15:23:45 +08:00
return false;
}
2020-03-14 22:14:16 -07:00
pinfo.mPlugin = (PluginInterface*)p();
2020-03-03 18:47:54 +08:00
2020-03-06 15:23:45 +08:00
return true;
2020-03-03 18:47:54 +08:00
}