File indexing completed on 2024-03-24 04:59:43
0001 /** 0002 * SPDX-FileCopyrightText: 2013 Albert Vaca <albertvaka@gmail.com> 0003 * 0004 * SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 0005 */ 0006 0007 #include "pluginloader.h" 0008 0009 #include <KPluginFactory> 0010 #include <KPluginMetaData> 0011 #include <QPluginLoader> 0012 #include <QStaticPlugin> 0013 #include <QVector> 0014 0015 #include "core_debug.h" 0016 #include "device.h" 0017 #include "kdeconnectconfig.h" 0018 #include "kdeconnectplugin.h" 0019 0020 PluginLoader *PluginLoader::instance() 0021 { 0022 static PluginLoader *instance = new PluginLoader(); 0023 return instance; 0024 } 0025 0026 PluginLoader::PluginLoader() 0027 { 0028 const QVector<KPluginMetaData> data = KPluginMetaData::findPlugins(QStringLiteral("kdeconnect")); 0029 for (const KPluginMetaData &metadata : data) { 0030 plugins[metadata.pluginId()] = metadata; 0031 } 0032 } 0033 0034 QStringList PluginLoader::getPluginList() const 0035 { 0036 return plugins.keys(); 0037 } 0038 0039 bool PluginLoader::doesPluginExist(const QString &name) const 0040 { 0041 return plugins.contains(name); 0042 } 0043 0044 KPluginMetaData PluginLoader::getPluginInfo(const QString &name) const 0045 { 0046 return plugins.value(name); 0047 } 0048 0049 KdeConnectPlugin *PluginLoader::instantiatePluginForDevice(const QString &pluginName, Device *device) const 0050 { 0051 const KPluginMetaData data = plugins.value(pluginName); 0052 if (!data.isValid()) { 0053 qCDebug(KDECONNECT_CORE) << "Plugin unknown" << pluginName; 0054 return nullptr; 0055 } 0056 0057 const QStringList outgoingInterfaces = data.value(QStringLiteral("X-KdeConnect-OutgoingPacketType"), QStringList()); 0058 const QVariantList args{QVariant::fromValue<Device *>(device), pluginName, outgoingInterfaces, data.iconName()}; 0059 0060 if (auto result = KPluginFactory::instantiatePlugin<KdeConnectPlugin>(data, device, args)) { 0061 qCDebug(KDECONNECT_CORE) << "Loaded plugin:" << data.pluginId(); 0062 return result.plugin; 0063 } else { 0064 qCDebug(KDECONNECT_CORE) << "Error loading plugin" << result.errorText; 0065 return nullptr; 0066 } 0067 } 0068 0069 QStringList PluginLoader::incomingCapabilities() const 0070 { 0071 QSet<QString> ret; 0072 for (const KPluginMetaData &service : plugins) { 0073 QStringList rawValues = service.value(QStringLiteral("X-KdeConnect-SupportedPacketType"), QStringList()); 0074 ret += QSet<QString>(rawValues.begin(), rawValues.end()); 0075 } 0076 return ret.values(); 0077 } 0078 0079 QStringList PluginLoader::outgoingCapabilities() const 0080 { 0081 QSet<QString> ret; 0082 for (const KPluginMetaData &service : plugins) { 0083 QStringList rawValues = service.value(QStringLiteral("X-KdeConnect-OutgoingPacketType"), QStringList()); 0084 ret += QSet<QString>(rawValues.begin(), rawValues.end()); 0085 } 0086 return ret.values(); 0087 } 0088 0089 QSet<QString> PluginLoader::pluginsForCapabilities(const QSet<QString> &incoming, const QSet<QString> &outgoing) const 0090 { 0091 QSet<QString> ret; 0092 0093 QString myDeviceType = KdeConnectConfig::instance().deviceType().toString(); 0094 0095 for (const KPluginMetaData &service : plugins) { 0096 // Check if the plugin support this device type 0097 const QStringList supportedDeviceTypes = service.rawData().value(QStringLiteral("X-KdeConnect-SupportedDeviceTypes")).toVariant().toStringList(); 0098 if (!supportedDeviceTypes.isEmpty()) { 0099 if (!supportedDeviceTypes.contains(myDeviceType)) { 0100 qCDebug(KDECONNECT_CORE) << "Not loading plugin" << service.pluginId() << "because this device of type" << myDeviceType 0101 << "is not supported. Supports:" << supportedDeviceTypes.join(QStringLiteral(", ")); 0102 continue; 0103 } 0104 } 0105 0106 // Check if capbilites intersect with the remote device 0107 const QStringList pluginIncomingCapabilities = service.rawData().value(QStringLiteral("X-KdeConnect-SupportedPacketType")).toVariant().toStringList(); 0108 const QStringList pluginOutgoingCapabilities = service.rawData().value(QStringLiteral("X-KdeConnect-OutgoingPacketType")).toVariant().toStringList(); 0109 0110 bool capabilitiesEmpty = (pluginIncomingCapabilities.isEmpty() && pluginOutgoingCapabilities.isEmpty()); 0111 if (!capabilitiesEmpty) { 0112 bool capabilitiesIntersect = (outgoing.intersects(QSet(pluginIncomingCapabilities.begin(), pluginIncomingCapabilities.end())) 0113 || incoming.intersects(QSet(pluginOutgoingCapabilities.begin(), pluginOutgoingCapabilities.end()))); 0114 0115 if (!capabilitiesIntersect) { 0116 qCDebug(KDECONNECT_CORE) << "Not loading plugin" << service.pluginId() << "because device doesn't support it"; 0117 continue; 0118 } 0119 } 0120 0121 // If we get here, the plugin can be loaded 0122 ret += service.pluginId(); 0123 } 0124 0125 return ret; 0126 }