2023-02-16 13:51:55 +08:00
|
|
|
|
// Copyright (C) 2011 ~ 2018 Deepin Technology Co., Ltd.
|
|
|
|
|
// SPDX-FileCopyrightText: 2018 - 2023 UnionTech Software Technology Co., Ltd.
|
2022-09-06 11:36:55 +08:00
|
|
|
|
//
|
|
|
|
|
// SPDX-License-Identifier: LGPL-3.0-or-later
|
2019-01-07 20:33:15 +08:00
|
|
|
|
|
|
|
|
|
#include "abstractpluginscontroller.h"
|
|
|
|
|
#include "pluginsiteminterface.h"
|
2021-03-20 12:10:45 +08:00
|
|
|
|
#include "utils.h"
|
2023-01-12 11:06:36 +08:00
|
|
|
|
#include "pluginmanagerinterface.h"
|
2019-01-07 20:33:15 +08:00
|
|
|
|
|
2021-03-20 12:10:45 +08:00
|
|
|
|
#include <DNotifySender>
|
2020-01-15 17:20:22 +08:00
|
|
|
|
#include <DSysInfo>
|
2021-03-20 12:10:45 +08:00
|
|
|
|
|
2019-01-07 20:33:15 +08:00
|
|
|
|
#include <QDebug>
|
|
|
|
|
#include <QDir>
|
2021-05-31 17:37:21 +08:00
|
|
|
|
#include <QMapIterator>
|
2019-01-07 20:33:15 +08:00
|
|
|
|
|
2019-01-30 17:49:17 +08:00
|
|
|
|
static const QStringList CompatiblePluginApiList {
|
|
|
|
|
"1.1.1",
|
2019-02-14 17:20:56 +08:00
|
|
|
|
"1.2",
|
2019-09-10 16:20:18 +08:00
|
|
|
|
"1.2.1",
|
2020-11-06 17:52:08 +08:00
|
|
|
|
"1.2.2",
|
2019-01-30 17:49:17 +08:00
|
|
|
|
DOCK_PLUGIN_API_VERSION
|
|
|
|
|
};
|
|
|
|
|
|
2019-01-07 20:33:15 +08:00
|
|
|
|
AbstractPluginsController::AbstractPluginsController(QObject *parent)
|
|
|
|
|
: QObject(parent)
|
2023-01-12 11:06:36 +08:00
|
|
|
|
, m_pluginManager(nullptr)
|
2019-01-07 20:33:15 +08:00
|
|
|
|
{
|
|
|
|
|
qApp->installEventFilter(this);
|
|
|
|
|
}
|
|
|
|
|
|
2021-05-25 13:05:45 +08:00
|
|
|
|
AbstractPluginsController::~AbstractPluginsController()
|
|
|
|
|
{
|
2021-08-02 17:00:24 +08:00
|
|
|
|
for (auto inter : m_pluginsMap.keys()) {
|
2021-05-25 13:05:45 +08:00
|
|
|
|
delete m_pluginsMap.value(inter).value("pluginloader");
|
2022-02-10 11:08:44 +08:00
|
|
|
|
m_pluginsMap[inter]["pluginloader"] = nullptr;
|
|
|
|
|
m_pluginsMap.remove(inter);
|
2021-05-25 13:05:45 +08:00
|
|
|
|
delete inter;
|
2022-02-10 11:08:44 +08:00
|
|
|
|
inter = nullptr;
|
2021-05-25 13:05:45 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-01-07 20:33:15 +08:00
|
|
|
|
void AbstractPluginsController::startLoader(PluginLoader *loader)
|
|
|
|
|
{
|
|
|
|
|
connect(loader, &PluginLoader::finished, loader, &PluginLoader::deleteLater, Qt::QueuedConnection);
|
2024-01-04 14:16:57 +08:00
|
|
|
|
connect(loader, &PluginLoader::pluginFound, this, [ = ](const QString &pluginFile) {
|
2021-05-31 17:37:21 +08:00
|
|
|
|
QPair<QString, PluginsItemInterface *> pair;
|
|
|
|
|
pair.first = pluginFile;
|
|
|
|
|
pair.second = nullptr;
|
|
|
|
|
m_pluginLoadMap.insert(pair, false);
|
|
|
|
|
});
|
2024-01-04 14:16:57 +08:00
|
|
|
|
connect(loader, &PluginLoader::pluginFound, this, &AbstractPluginsController::loadPlugin, Qt::QueuedConnection);
|
2019-01-07 20:33:15 +08:00
|
|
|
|
|
2021-03-20 12:10:45 +08:00
|
|
|
|
int delay = Utils::SettingValue("com.deepin.dde.dock", "/com/deepin/dde/dock/", "delay-plugins-time", 0).toInt();
|
|
|
|
|
QTimer::singleShot(delay, loader, [ = ] { loader->start(QThread::LowestPriority); });
|
2019-01-07 20:33:15 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void AbstractPluginsController::displayModeChanged()
|
|
|
|
|
{
|
|
|
|
|
const Dock::DisplayMode displayMode = qApp->property(PROP_DISPLAY_MODE).value<Dock::DisplayMode>();
|
|
|
|
|
const auto inters = m_pluginsMap.keys();
|
|
|
|
|
|
|
|
|
|
for (auto inter : inters)
|
|
|
|
|
inter->displayModeChanged(displayMode);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void AbstractPluginsController::positionChanged()
|
|
|
|
|
{
|
|
|
|
|
const Dock::Position position = qApp->property(PROP_POSITION).value<Dock::Position>();
|
|
|
|
|
const auto inters = m_pluginsMap.keys();
|
|
|
|
|
|
|
|
|
|
for (auto inter : inters)
|
|
|
|
|
inter->positionChanged(position);
|
|
|
|
|
}
|
|
|
|
|
|
2021-03-09 13:29:02 +08:00
|
|
|
|
void AbstractPluginsController::loadPlugin(const QString &pluginFile)
|
2019-01-07 20:33:15 +08:00
|
|
|
|
{
|
2021-05-25 13:05:45 +08:00
|
|
|
|
QPluginLoader *pluginLoader = new QPluginLoader(pluginFile, this);
|
2019-01-30 17:49:17 +08:00
|
|
|
|
const QJsonObject &meta = pluginLoader->metaData().value("MetaData").toObject();
|
|
|
|
|
const QString &pluginApi = meta.value("api").toString();
|
2019-04-17 13:07:20 +08:00
|
|
|
|
bool pluginIsValid = true;
|
2019-09-10 16:20:18 +08:00
|
|
|
|
if (pluginApi.isEmpty() || !CompatiblePluginApiList.contains(pluginApi)) {
|
2020-06-30 09:54:12 +08:00
|
|
|
|
qDebug() << objectName()
|
2021-05-31 17:37:21 +08:00
|
|
|
|
<< "plugin api version not matched! expect versions:" << CompatiblePluginApiList
|
|
|
|
|
<< ", got version:" << pluginApi
|
|
|
|
|
<< ", the plugin file is:" << pluginFile;
|
2019-04-17 13:07:20 +08:00
|
|
|
|
|
|
|
|
|
pluginIsValid = false;
|
2019-01-07 20:33:15 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
PluginsItemInterface *interface = qobject_cast<PluginsItemInterface *>(pluginLoader->instance());
|
2019-09-10 16:20:18 +08:00
|
|
|
|
if (!interface) {
|
2020-06-30 09:54:12 +08:00
|
|
|
|
qDebug() << objectName() << "load plugin failed!!!" << pluginLoader->errorString() << pluginFile;
|
2019-04-17 13:07:20 +08:00
|
|
|
|
|
2019-01-07 20:33:15 +08:00
|
|
|
|
pluginLoader->unload();
|
|
|
|
|
pluginLoader->deleteLater();
|
2019-04-17 13:07:20 +08:00
|
|
|
|
|
|
|
|
|
pluginIsValid = false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!pluginIsValid) {
|
2021-08-02 17:00:24 +08:00
|
|
|
|
for (auto &pair : m_pluginLoadMap.keys()) {
|
2021-04-27 10:30:00 +09:00
|
|
|
|
if (pair.first == pluginFile) {
|
|
|
|
|
m_pluginLoadMap.remove(pair);
|
|
|
|
|
}
|
|
|
|
|
}
|
2019-04-17 13:07:20 +08:00
|
|
|
|
QString notifyMessage(tr("The plugin %1 is not compatible with the system."));
|
|
|
|
|
Dtk::Core::DUtil::DNotifySender(notifyMessage.arg(QFileInfo(pluginFile).fileName())).appIcon("dialog-warning").call();
|
2019-01-07 20:33:15 +08:00
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2021-05-31 17:37:21 +08:00
|
|
|
|
QMapIterator<QPair<QString, PluginsItemInterface *>, bool> it(m_pluginLoadMap);
|
|
|
|
|
while (it.hasNext()) {
|
|
|
|
|
it.next();
|
|
|
|
|
if (it.key().first == pluginFile) {
|
2021-07-15 13:31:20 +08:00
|
|
|
|
m_pluginLoadMap.remove(it.key());
|
|
|
|
|
QPair<QString, PluginsItemInterface *> newPair;
|
|
|
|
|
newPair.first = pluginFile;
|
|
|
|
|
newPair.second = interface;
|
|
|
|
|
m_pluginLoadMap.insert(newPair, false);
|
2021-04-27 10:30:00 +09:00
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
2021-04-26 15:53:52 +09:00
|
|
|
|
|
2020-11-06 17:52:08 +08:00
|
|
|
|
// 保存 PluginLoader 对象指针
|
|
|
|
|
QMap<QString, QObject *> interfaceData;
|
|
|
|
|
interfaceData["pluginloader"] = pluginLoader;
|
|
|
|
|
m_pluginsMap.insert(interface, interfaceData);
|
2023-01-12 11:06:36 +08:00
|
|
|
|
|
|
|
|
|
PluginManagerInterface * pluginManager = dynamic_cast<PluginManagerInterface *>(interface);
|
|
|
|
|
if (pluginManager) {
|
|
|
|
|
m_pluginManager = pluginManager;
|
|
|
|
|
connect(m_pluginManager, &PluginManagerInterface::pluginLoadFinished, this, &AbstractPluginsController::pluginLoaderFinished);
|
2019-01-07 20:33:15 +08:00
|
|
|
|
}
|
|
|
|
|
|
2019-06-28 16:58:31 +08:00
|
|
|
|
// NOTE(justforlxz): 插件的所有初始化工作都在init函数中进行,
|
|
|
|
|
// loadPlugin函数是按队列执行的,initPlugin函数会有可能导致
|
|
|
|
|
// 函数执行被阻塞。
|
2024-01-04 14:14:06 +08:00
|
|
|
|
QMetaObject::invokeMethod(this, std::bind(&AbstractPluginsController::initPlugin, this, interface), Qt::QueuedConnection);
|
2019-01-07 20:33:15 +08:00
|
|
|
|
}
|
|
|
|
|
|
2019-09-10 16:20:18 +08:00
|
|
|
|
void AbstractPluginsController::initPlugin(PluginsItemInterface *interface)
|
|
|
|
|
{
|
2022-02-10 11:08:44 +08:00
|
|
|
|
if (!interface)
|
|
|
|
|
return;
|
|
|
|
|
|
2019-01-07 20:33:15 +08:00
|
|
|
|
qDebug() << objectName() << "init plugin: " << interface->pluginName();
|
|
|
|
|
interface->init(this);
|
2021-04-27 10:30:00 +09:00
|
|
|
|
|
|
|
|
|
for (const auto &pair : m_pluginLoadMap.keys()) {
|
|
|
|
|
if (pair.second == interface)
|
|
|
|
|
m_pluginLoadMap.insert(pair, true);
|
|
|
|
|
}
|
|
|
|
|
|
2019-01-07 20:33:15 +08:00
|
|
|
|
qDebug() << objectName() << "init plugin finished: " << interface->pluginName();
|
2023-03-22 20:11:24 +08:00
|
|
|
|
|
2019-01-07 20:33:15 +08:00
|
|
|
|
}
|
|
|
|
|
|
2023-01-12 11:06:36 +08:00
|
|
|
|
bool AbstractPluginsController::eventFilter(QObject *object, QEvent *event)
|
2019-01-07 20:33:15 +08:00
|
|
|
|
{
|
2023-01-12 11:06:36 +08:00
|
|
|
|
if (object != qApp || event->type() != QEvent::DynamicPropertyChange)
|
2019-01-07 20:33:15 +08:00
|
|
|
|
return false;
|
|
|
|
|
|
2023-01-12 11:06:36 +08:00
|
|
|
|
QDynamicPropertyChangeEvent *const dpce = static_cast<QDynamicPropertyChangeEvent *>(event);
|
2019-01-07 20:33:15 +08:00
|
|
|
|
const QString propertyName = dpce->propertyName();
|
|
|
|
|
|
|
|
|
|
if (propertyName == PROP_POSITION)
|
|
|
|
|
positionChanged();
|
|
|
|
|
else if (propertyName == PROP_DISPLAY_MODE)
|
|
|
|
|
displayModeChanged();
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
2022-11-30 11:13:45 +08:00
|
|
|
|
|
2023-01-12 11:06:36 +08:00
|
|
|
|
PluginManagerInterface *AbstractPluginsController::pluginManager() const
|
2022-11-30 11:13:45 +08:00
|
|
|
|
{
|
2023-01-12 11:06:36 +08:00
|
|
|
|
return m_pluginManager;
|
2022-11-30 11:13:45 +08:00
|
|
|
|
}
|