From df3581459a1c66146748e4872edd5f35911bba8a Mon Sep 17 00:00:00 2001 From: Aleix Pol Date: Tue, 8 Sep 2015 17:28:47 +0200 Subject: [PATCH] Add a test that makes sure that capabilities are gathered correctly While at it, fix the logic, because it wasn't working all that well. Reviewed by Albert Vaca --- core/device.cpp | 47 +++++++++++++------ core/device.h | 5 ++- tests/CMakeLists.txt | 1 + tests/pluginloadtest.cpp | 97 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 136 insertions(+), 14 deletions(-) create mode 100644 tests/pluginloadtest.cpp diff --git a/core/device.cpp b/core/device.cpp index c1a753515..64ab0fb4f 100644 --- a/core/device.cpp +++ b/core/device.cpp @@ -76,7 +76,7 @@ Device::Device(QObject* parent, const NetworkPackage& identityPackage, DeviceLin , m_protocolVersion(identityPackage.get("protocolVersion")) { addLink(identityPackage, dl); - + //Register in bus QDBusConnection::sessionBus().registerObject(dbusPath(), this, QDBusConnection::ExportScriptableContents | QDBusConnection::ExportAdaptors); @@ -109,6 +109,7 @@ void Device::reloadPlugins() QHash newPluginMap; QMultiMap newPluginsByIncomingInterface; QMultiMap newPluginsByOutgoingInterface; + QSet supportedIncomingInterfaces; QStringList missingPlugins; if (isPaired() && isReachable()) { //Do not load any plugin for unpaired devices, nor useless loading them for unreachable devices @@ -119,12 +120,7 @@ void Device::reloadPlugins() //Code borrowed from KWin foreach (const QString& pluginName, loader->getPluginList()) { - QString enabledKey = pluginName + QString::fromLatin1("Enabled"); - - bool isPluginEnabled = (pluginStates.hasKey(enabledKey) ? pluginStates.readEntry(enabledKey, false) - : loader->getPluginInfo(pluginName).isEnabledByDefault()); - - if (isPluginEnabled) { + if (isPluginEnabled(pluginName)) { KdeConnectPlugin* plugin = m_plugins.take(pluginName); QStringList incomingInterfaces, outgoingInterfaces; if (plugin) { @@ -135,6 +131,7 @@ void Device::reloadPlugins() incomingInterfaces = KPluginMetaData::readStringList(service.rawData(), "X-KdeConnect-SupportedPackageType"); outgoingInterfaces = KPluginMetaData::readStringList(service.rawData(), "X-KdeConnect-OutgoingPackageType"); } + supportedIncomingInterfaces += incomingInterfaces.toSet(); //If we don't find intersection with the received on one end and the sent on the other, we don't //let the plugin stay @@ -167,22 +164,28 @@ void Device::reloadPlugins() //Erase all left plugins in the original map (meaning that we don't want //them anymore, otherwise they would have been moved to the newPluginMap) + const QStringList newSupportedIncomingInterfaces = supportedIncomingInterfaces.toList(); + const bool capabilitiesChanged = (m_pluginsByOutgoingInterface != newPluginsByOutgoingInterface + || m_supportedIncomingInterfaces != newSupportedIncomingInterfaces); qDeleteAll(m_plugins); m_plugins = newPluginMap; - m_pluginsByIncomingInterface = newPluginsByIncomingInterface; m_pluginsByOutgoingInterface = newPluginsByOutgoingInterface; + m_supportedIncomingInterfaces = newSupportedIncomingInterfaces; + m_pluginsByIncomingInterface = newPluginsByIncomingInterface; m_missingPlugins = missingPlugins; Q_FOREACH(KdeConnectPlugin* plugin, m_plugins) { plugin->connected(); } - Q_EMIT pluginsChanged(); - NetworkPackage np(PACKAGE_TYPE_CAPABILITIES); - np.set("SupportedIncomingInterfaces", m_pluginsByIncomingInterface.keys()); - np.set("SupportedOutgoingInterfaces", m_pluginsByOutgoingInterface.keys()); - sendPackage(np); + if (capabilitiesChanged) + { + NetworkPackage np(PACKAGE_TYPE_CAPABILITIES); + np.set("SupportedIncomingInterfaces", newSupportedIncomingInterfaces); + np.set("SupportedOutgoingInterfaces", newPluginsByOutgoingInterface.keys()); + sendPackage(np); + } } QString Device::pluginsConfigFile() const @@ -544,3 +547,21 @@ KdeConnectPlugin* Device::plugin(const QString& pluginName) const { return m_plugins[pluginName]; } + +void Device::setPluginEnabled(const QString& pluginName, bool enabled) +{ + KConfigGroup pluginStates = KSharedConfig::openConfig(pluginsConfigFile())->group("Plugins"); + + const QString enabledKey = pluginName + QStringLiteral("Enabled"); + pluginStates.writeEntry(enabledKey, enabled); + reloadPlugins(); +} + +bool Device::isPluginEnabled(const QString& pluginName) const +{ + const QString enabledKey = pluginName + QStringLiteral("Enabled"); + KConfigGroup pluginStates = KSharedConfig::openConfig(pluginsConfigFile())->group("Plugins"); + + return (pluginStates.hasKey(enabledKey) ? pluginStates.readEntry(enabledKey, false) + : PluginLoader::instance()->getPluginInfo(pluginName).isEnabledByDefault()); +} diff --git a/core/device.h b/core/device.h index 2e1d48b90..6814c4adb 100644 --- a/core/device.h +++ b/core/device.h @@ -104,7 +104,9 @@ public: Q_SCRIPTABLE QString pluginsConfigFile() const; - KdeConnectPlugin* plugin(const QString& plugin) const; + KdeConnectPlugin* plugin(const QString& pluginName) const; + void setPluginEnabled(const QString& pluginName, bool enabled); + bool isPluginEnabled(const QString& pluginName) const; public Q_SLOTS: ///sends a @p np package to the device @@ -156,6 +158,7 @@ private: //Fields (TODO: dPointer!) QTimer m_pairingTimeut; QSet m_incomingCapabilities; QSet m_outgoingCapabilities; + QStringList m_supportedIncomingInterfaces; QStringList m_missingPlugins; }; diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index f921881be..0ebc91998 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -14,6 +14,7 @@ set(kdeconnect_libraries qca-qt5 ) +ecm_add_test(pluginloadtest.cpp LINK_LIBRARIES ${kdeconnect_libraries}) ecm_add_test(sendfiletest.cpp LINK_LIBRARIES ${kdeconnect_libraries}) ecm_add_test(networkpackagetests.cpp LINK_LIBRARIES ${kdeconnect_libraries}) ecm_add_test(testsocketlinereader.cpp ../core/backends/lan/socketlinereader.cpp TEST_NAME testsocketlinereader LINK_LIBRARIES ${kdeconnect_libraries}) diff --git a/tests/pluginloadtest.cpp b/tests/pluginloadtest.cpp new file mode 100644 index 000000000..4b175a25c --- /dev/null +++ b/tests/pluginloadtest.cpp @@ -0,0 +1,97 @@ +/** + * Copyright 2015 Aleix Pol Gonzalez + * + * 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 2 of + * the License or (at your option) version 3 or any later version + * accepted by the membership of KDE e.V. (or its successor approved + * by the membership of KDE e.V.), which shall act as a proxy + * defined in Section 14 of version 3 of the license. + * + * 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 . + */ + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "core/daemon.h" +#include "core/device.h" +#include "core/kdeconnectplugin.h" +#include "kdeconnect-version.h" + +class TestDaemon : public Daemon +{ +Q_OBJECT +public: + TestDaemon(QObject* parent = Q_NULLPTR) + : Daemon(parent, true) + , m_nam(Q_NULLPTR) + { + } + + void requestPairing(Device* d) Q_DECL_OVERRIDE + { + d->acceptPairing(); + } + + void reportError(const QString & title, const QString & description) Q_DECL_OVERRIDE + { + qWarning() << "error:" << title << description; + } + + QNetworkAccessManager* networkAccessManager() Q_DECL_OVERRIDE + { + if (!m_nam) { + m_nam = new KIO::AccessManager(this); + } + return m_nam; + } + +private: + QNetworkAccessManager* m_nam; +}; + +class PluginLoadTest : public QObject +{ + Q_OBJECT + public: + PluginLoadTest() : mDaemon(new TestDaemon) { + QStandardPaths::setTestModeEnabled(true); + } + + private Q_SLOTS: + void testPlugins() { + Device* d = mDaemon->devicesList().first(); + QVERIFY(d->isPaired()); + QVERIFY(d->isReachable()); + + d->setPluginEnabled("kdeconnect_mousepad", false); + QCOMPARE(d->isPluginEnabled("kdeconnect_mousepad"), false); + QVERIFY(d->missingPlugins().contains("kdeconnect_remotecontrol")); + + d->setPluginEnabled("kdeconnect_mousepad", true); + QCOMPARE(d->isPluginEnabled("kdeconnect_mousepad"), true); + QVERIFY(!d->missingPlugins().contains("kdeconnect_remotecontrol")); + } + + private: + TestDaemon* mDaemon; +}; + +QTEST_MAIN(PluginLoadTest); + +#include "pluginloadtest.moc"