mirror of
https://github.com/linuxdeepin/dde-dock.git
synced 2025-06-04 09:23:03 +00:00
fix: 插件加载的时候过滤掉和当前进程使用的dtkcore版本不同的插件
在加载插件之前,拿到当前进程使用的dtkCore,然后依次判断每个插件依赖的dtkCore是否和当前的dtkCore一致,如果出现不一致的情况,则不加载 Log: 增加对不同版本插件的限制 Task: https://pms.uniontech.com/zentao/task-view-81282.html Change-Id: I7ffc7d94f33adc4edcb8191622c5f7448d70ab32
This commit is contained in:
parent
32894dd413
commit
b543d92151
@ -52,7 +52,7 @@ AbstractPluginsController::AbstractPluginsController(QObject *parent)
|
||||
|
||||
AbstractPluginsController::~AbstractPluginsController()
|
||||
{
|
||||
for (auto inter: m_pluginsMap.keys()) {
|
||||
for (auto inter : m_pluginsMap.keys()) {
|
||||
m_pluginsMap.remove(inter);
|
||||
delete m_pluginsMap.value(inter).value("pluginloader");
|
||||
delete inter;
|
||||
@ -150,7 +150,7 @@ PluginsItemInterface *AbstractPluginsController::pluginInterAt(const QString &it
|
||||
}
|
||||
|
||||
PluginsItemInterface *AbstractPluginsController::pluginInterAt(QObject *destItem)
|
||||
{
|
||||
{
|
||||
QMapIterator<PluginsItemInterface *, QMap<QString, QObject *>> it(m_pluginsMap);
|
||||
while (it.hasNext()) {
|
||||
it.next();
|
||||
@ -165,7 +165,7 @@ PluginsItemInterface *AbstractPluginsController::pluginInterAt(QObject *destItem
|
||||
void AbstractPluginsController::startLoader(PluginLoader *loader)
|
||||
{
|
||||
connect(loader, &PluginLoader::finished, loader, &PluginLoader::deleteLater, Qt::QueuedConnection);
|
||||
connect(loader, &PluginLoader::pluginFounded, this, [ = ](const QString &pluginFile){
|
||||
connect(loader, &PluginLoader::pluginFounded, this, [ = ](const QString &pluginFile) {
|
||||
QPair<QString, PluginsItemInterface *> pair;
|
||||
pair.first = pluginFile;
|
||||
pair.second = nullptr;
|
||||
@ -222,7 +222,7 @@ void AbstractPluginsController::loadPlugin(const QString &pluginFile)
|
||||
}
|
||||
|
||||
if (!pluginIsValid) {
|
||||
for (auto &pair: m_pluginLoadMap.keys()) {
|
||||
for (auto &pair : m_pluginLoadMap.keys()) {
|
||||
if (pair.first == pluginFile) {
|
||||
m_pluginLoadMap.remove(pair);
|
||||
}
|
||||
@ -233,8 +233,8 @@ void AbstractPluginsController::loadPlugin(const QString &pluginFile)
|
||||
}
|
||||
|
||||
if (interface->pluginName() == "multitasking") {
|
||||
if (qEnvironmentVariable("XDG_SESSION_TYPE").contains("wayland") or Dtk::Core::DSysInfo::deepinType() == Dtk::Core::DSysInfo::DeepinServer){
|
||||
for (auto &pair: m_pluginLoadMap.keys()) {
|
||||
if (qEnvironmentVariable("XDG_SESSION_TYPE").contains("wayland") or Dtk::Core::DSysInfo::deepinType() == Dtk::Core::DSysInfo::DeepinServer) {
|
||||
for (auto &pair : m_pluginLoadMap.keys()) {
|
||||
if (pair.first == pluginFile) {
|
||||
m_pluginLoadMap.remove(pair);
|
||||
}
|
||||
|
@ -37,7 +37,7 @@ void PluginLoader::run()
|
||||
QDir pluginsDir(m_pluginDirPath);
|
||||
const QStringList files = pluginsDir.entryList(QDir::Files);
|
||||
|
||||
auto getDisablePluginList = [ = ]{
|
||||
auto getDisablePluginList = [ = ] {
|
||||
if (QGSettings::isSchemaInstalled("com.deepin.dde.dock.disableplugins")) {
|
||||
QGSettings gsetting("com.deepin.dde.dock.disableplugins", "/com/deepin/dde/dock/disableplugins/");
|
||||
return gsetting.get("disable-plugins-list").toStringList();
|
||||
@ -47,11 +47,12 @@ void PluginLoader::run()
|
||||
|
||||
const QStringList disable_plugins_list = getDisablePluginList();
|
||||
|
||||
const QString dtkCoreName = dtkCoreFileName();
|
||||
|
||||
QStringList plugins;
|
||||
|
||||
// 查找可用插件
|
||||
for (QString file : files)
|
||||
{
|
||||
for (QString file : files) {
|
||||
if (!QLibrary::isLibrary(file))
|
||||
continue;
|
||||
|
||||
@ -63,6 +64,12 @@ void PluginLoader::run()
|
||||
qDebug() << "disable loading plugin:" << file;
|
||||
continue;
|
||||
}
|
||||
// 判断当前进程加载的dtkcore库是否和当前库加载的dtkcore的库为同一个,如果不同,则无需加载,
|
||||
// 否则在加载dtkcore的时候会报错(dtkcore内部判断如果加载两次会抛出错误)
|
||||
QString libUsedDtkCore = libUsedDtkCoreFileName(pluginsDir.absoluteFilePath(file));
|
||||
if (!libUsedDtkCore.isEmpty() && libUsedDtkCore != dtkCoreName)
|
||||
continue;
|
||||
|
||||
plugins << file;
|
||||
}
|
||||
for (auto plugin : plugins) {
|
||||
@ -71,3 +78,103 @@ void PluginLoader::run()
|
||||
|
||||
emit finished();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 获取当前进程使用的dtkcore库的文件名
|
||||
* @return 当前进程使用的dtkCore库的文件名
|
||||
*/
|
||||
QString PluginLoader::dtkCoreFileName()
|
||||
{
|
||||
QFile f("/proc/self/maps");
|
||||
if (!f.open(QIODevice::ReadOnly))
|
||||
return QString();
|
||||
|
||||
const QByteArray &data = f.readAll();
|
||||
QTextStream ts(data);
|
||||
while (Q_UNLIKELY(!ts.atEnd())) {
|
||||
const QString line = ts.readLine();
|
||||
const QStringList &maps = line.split(' ', QString::SplitBehavior::SkipEmptyParts);
|
||||
if (Q_UNLIKELY(maps.size() < 6))
|
||||
continue;
|
||||
|
||||
QFileInfo info(maps.value(5));
|
||||
QString infoAbPath = info.absoluteFilePath();
|
||||
if (info.fileName().contains("dtkcore")) {
|
||||
infoAbPath = realFileName(infoAbPath);
|
||||
if (infoAbPath.contains("/")) {
|
||||
int pathIndex = infoAbPath.lastIndexOf("/");
|
||||
infoAbPath = infoAbPath.mid(pathIndex + 1).trimmed();
|
||||
}
|
||||
|
||||
f.close();
|
||||
return infoAbPath;
|
||||
}
|
||||
}
|
||||
|
||||
f.close();
|
||||
return QString();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 返回某个so库使用的dtkcore库文件名
|
||||
* @param 用于获取dtkcore库的so库文件名
|
||||
* @return 返回使用的dtkcore库文件名
|
||||
*/
|
||||
QString PluginLoader::libUsedDtkCoreFileName(const QString &fileName)
|
||||
{
|
||||
QString lddCommand = QString("ldd -r %1").arg(fileName);
|
||||
FILE *fp = popen(lddCommand.toLocal8Bit().data(), "r");
|
||||
if (fp) {
|
||||
char buf[2000] = {0};
|
||||
while (fgets(buf, sizeof(buf), fp)) {
|
||||
QString rowResult = buf;
|
||||
rowResult = rowResult.trimmed();
|
||||
if (rowResult.contains("dtkcore")) {
|
||||
QStringList coreSplits = rowResult.split("=>");
|
||||
if (coreSplits.size() < 2)
|
||||
continue;
|
||||
|
||||
pclose(fp);
|
||||
QString dtkCorePath = coreSplits[1];
|
||||
|
||||
// 删除后面的括号的内容
|
||||
int addrIndex = dtkCorePath.indexOf("(0x");
|
||||
dtkCorePath = realFileName(dtkCorePath.left(addrIndex).trimmed());
|
||||
if (dtkCorePath.contains("/")) {
|
||||
int pathIndex = dtkCorePath.lastIndexOf("/");
|
||||
dtkCorePath = dtkCorePath.mid(pathIndex + 1).trimmed();
|
||||
}
|
||||
|
||||
return dtkCorePath;
|
||||
}
|
||||
}
|
||||
pclose(fp);
|
||||
}
|
||||
return QString();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 返回软连接对应的实际的文件名
|
||||
* @param 当前软连接的文件名
|
||||
* @return 软连接对应的库的实际的文件名
|
||||
*/
|
||||
QString PluginLoader::realFileName(QString fileName)
|
||||
{
|
||||
QString command = QString("ls %1 -al").arg(fileName);
|
||||
FILE *fp = popen(command.toLocal8Bit().data(), "r");
|
||||
if (fp) {
|
||||
char buf[2000] = {0};
|
||||
if (fgets(buf, sizeof(buf), fp)) {
|
||||
QString rowInfo = buf;
|
||||
if (rowInfo.contains("->")) {
|
||||
pclose(fp);
|
||||
QStringList fileInfos = rowInfo.split("->");
|
||||
QString srcFileName = fileInfos[1];
|
||||
srcFileName = srcFileName.trimmed();
|
||||
return srcFileName;
|
||||
}
|
||||
}
|
||||
pclose(fp);
|
||||
}
|
||||
return fileName;
|
||||
}
|
||||
|
@ -38,6 +38,10 @@ signals:
|
||||
protected:
|
||||
void run();
|
||||
|
||||
QString dtkCoreFileName();
|
||||
QString libUsedDtkCoreFileName(const QString &fileName);
|
||||
QString realFileName(QString fileName); // 获取软连接的真实文件的路径
|
||||
|
||||
private:
|
||||
QString m_pluginDirPath;
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user