diff --git a/core/backends/devicelink.cpp b/core/backends/devicelink.cpp index bb190fd8d..d063019f1 100644 --- a/core/backends/devicelink.cpp +++ b/core/backends/devicelink.cpp @@ -28,9 +28,18 @@ DeviceLink::DeviceLink(const QString& deviceId, LinkProvider* parent, Connection , mDeviceId(deviceId) , mConnectionSource(connectionSource) , mLinkProvider(parent) + , mPairStatus(NotPaired) { Q_ASSERT(!deviceId.isEmpty()); setProperty("deviceId", deviceId); } +void DeviceLink::setPairStatus(DeviceLink::PairStatus status) +{ + if (mPairStatus != status) { + mPairStatus = status; + Q_EMIT pairStatusChanged(status); + } +} + diff --git a/core/backends/devicelink.h b/core/backends/devicelink.h index 9c9b419b9..1de418591 100644 --- a/core/backends/devicelink.h +++ b/core/backends/devicelink.h @@ -37,6 +37,7 @@ class DeviceLink Q_OBJECT public: + enum PairStatus : bool { NotPaired, Paired }; enum ConnectionStarted : bool { Locally, Remotely }; DeviceLink(const QString& deviceId, LinkProvider* parent, ConnectionStarted connectionSource); @@ -47,16 +48,21 @@ public: const QString& deviceId() { return mDeviceId; } LinkProvider* provider() { return mLinkProvider; } - virtual PairingHandler* createPairingHandler(Device* device) = 0; virtual bool sendPackage(NetworkPackage& np) = 0; virtual bool sendPackageEncrypted(NetworkPackage& np) = 0; - ConnectionStarted connectionSource() const { - return mConnectionSource; - } + //user actions + virtual void requestPairing() = 0; + virtual void unpair() = 0; + + ConnectionStarted connectionSource() const { return mConnectionSource; } + + PairStatus pairStatus() const { return mPairStatus; } + void setPairStatus(PairStatus status); Q_SIGNALS: void receivedPackage(const NetworkPackage& np); + void pairStatusChanged(DeviceLink::PairStatus status); protected: QCA::PrivateKey mPrivateKey; @@ -65,6 +71,7 @@ private: const QString mDeviceId; const ConnectionStarted mConnectionSource; LinkProvider* mLinkProvider; + PairStatus mPairStatus; }; diff --git a/core/backends/lan/landevicelink.cpp b/core/backends/lan/landevicelink.cpp index 169ff8db3..2d3470d48 100644 --- a/core/backends/lan/landevicelink.cpp +++ b/core/backends/lan/landevicelink.cpp @@ -25,7 +25,7 @@ #include "uploadjob.h" #include "downloadjob.h" #include "socketlinereader.h" -#include "lanpairinghandler.h" +#include "lanlinkprovider.h" LanDeviceLink::LanDeviceLink(const QString& deviceId, LinkProvider* parent, QSslSocket* socket, ConnectionStarted connectionSource) : DeviceLink(deviceId, parent, connectionSource) @@ -49,11 +49,6 @@ QString LanDeviceLink::name() return "LanLink"; // Should be same in both android and kde version } -PairingHandler* LanDeviceLink::createPairingHandler(Device* device) -{ - return new LanPairingHandler(device->id()); -} - bool LanDeviceLink::sendPackageEncrypted(NetworkPackage& np) { if (np.hasPayload()) { @@ -124,3 +119,13 @@ void LanDeviceLink::dataReceived() } } + +void LanDeviceLink::requestPairing() +{ + qobject_cast(provider())->requestPairing(deviceId()); +} + +void LanDeviceLink::unpair() +{ + setPairStatus(NotPaired); +} diff --git a/core/backends/lan/landevicelink.h b/core/backends/lan/landevicelink.h index 6c72fe6ce..5bc7a8f21 100644 --- a/core/backends/lan/landevicelink.h +++ b/core/backends/lan/landevicelink.h @@ -39,18 +39,22 @@ public: LanDeviceLink(const QString& deviceId, LinkProvider* parent, QSslSocket* socket, ConnectionStarted connectionSource); virtual QString name() Q_DECL_OVERRIDE; - virtual PairingHandler* createPairingHandler(Device* device) Q_DECL_OVERRIDE; bool sendPackage(NetworkPackage& np) override; bool sendPackageEncrypted(NetworkPackage& np) override; UploadJob* sendPayload(NetworkPackage& np); + virtual void unpair() override; + + void requestPairing(); + private Q_SLOTS: void dataReceived(); private: SocketLineReader* mSocketLineReader; - bool onSsl; + QCA::PublicKey m_publicKey; + QSslCertificate m_certificate; }; #endif diff --git a/core/backends/lan/lanlinkprovider.cpp b/core/backends/lan/lanlinkprovider.cpp index 5ff16d7f3..6012612d1 100644 --- a/core/backends/lan/lanlinkprovider.cpp +++ b/core/backends/lan/lanlinkprovider.cpp @@ -37,6 +37,7 @@ #include "../../daemon.h" #include "landevicelink.h" +#include "lanpairinghandler.h" #include #include #include @@ -269,7 +270,7 @@ void LanLinkProvider::sslErrors(const QList& errors) disconnect(socket, SIGNAL(encrypted()), this, SLOT(encrypted())); disconnect(socket, SIGNAL(sslErrors(QList)), this, SLOT(sslErrors(QList))); - foreach(QSslError error, errors) { + foreach(const QSslError &error, errors) { qCDebug(KDECONNECT_CORE) << "SSL Error :" << error.errorString(); switch (error.error()) { case QSslError::CertificateSignatureFailed: @@ -438,7 +439,23 @@ void LanLinkProvider::addLink(const QString& deviceId, QSslSocket* socket, Netwo } mLinks[deviceLink->deviceId()] = deviceLink; + LanPairingHandler* ph = mPairingHandlers.value(deviceLink->deviceId()); + if (ph) { + ph->setDeviceLink(deviceLink); + } Q_EMIT onConnectionReceived(*receivedPackage, deviceLink); } + +void LanLinkProvider::requestPairing(const QString& deviceId) +{ + LanPairingHandler* ph = mPairingHandlers.value(deviceId); + if (!ph) { + new LanPairingHandler(deviceId); + ph->setDeviceLink(mLinks[deviceId]); + mPairingHandlers[deviceId] = ph; + } + + ph->requestPairing(); +} diff --git a/core/backends/lan/lanlinkprovider.h b/core/backends/lan/lanlinkprovider.h index e51183c89..1ab8fde41 100644 --- a/core/backends/lan/lanlinkprovider.h +++ b/core/backends/lan/lanlinkprovider.h @@ -31,6 +31,7 @@ #include "server.h" #include "landevicelink.h" +class LanPairingHandler; class LanLinkProvider : public LinkProvider { @@ -43,6 +44,8 @@ public: QString name() override { return "LanLinkProvider"; } int priority() override { return PRIORITY_HIGH; } + void requestPairing(const QString &deviceId); + public Q_SLOTS: virtual void onNetworkChange() override; virtual void onStart() override; @@ -70,6 +73,7 @@ private: quint16 mTcpPort; QMap mLinks; + QMap mPairingHandlers; struct PendingConnect { NetworkPackage* np; diff --git a/core/backends/lan/lanpairinghandler.cpp b/core/backends/lan/lanpairinghandler.cpp index c28998e97..d28456ced 100644 --- a/core/backends/lan/lanpairinghandler.cpp +++ b/core/backends/lan/lanpairinghandler.cpp @@ -30,20 +30,12 @@ LanPairingHandler::LanPairingHandler(const QString& deviceId) : PairingHandler() , m_deviceId(deviceId) + , m_status(NotPaired) { m_pairingTimeout.setSingleShot(true); m_pairingTimeout.setInterval(30 * 1000); //30 seconds of timeout connect(&m_pairingTimeout, SIGNAL(timeout()), this, SLOT(pairingTimeout())); -/* - m_publicKey = KdeConnectConfig::instance()->getDeviceProperty(deviceId, "publicKey", QString()); - m_certificate = KdeConnectConfig::instance()->getDeviceProperty(deviceId, "certificate", QString()); -*/ - if (!m_publicKey.isNull()) { - setPairStatus(PairStatus::Paired); - } else { - setPairStatus(PairStatus::NotPaired); - } } void LanPairingHandler::createPairPackage(NetworkPackage& np) @@ -65,8 +57,8 @@ void LanPairingHandler::packageReceived(const NetworkPackage& np) if (wantsPair == isPaired()) { // qCDebug(KDECONNECT_CORE) << "Already" << (wantsPair? "paired":"unpaired"); if (isPairRequested()) { - setPairStatus(PairStatus::NotPaired); - Q_EMIT pairingFailed(i18n("Canceled by other peer")); + setInternalPairStatus(NotPaired); + Q_EMIT pairingError(i18n("Canceled by other peer")); return; } else if (isPaired()) { /** @@ -74,7 +66,7 @@ void LanPairingHandler::packageReceived(const NetworkPackage& np) * and we don't know it, unpair it internally */ KdeConnectConfig::instance()->removeTrustedDevice(m_deviceId); - setPairStatus(PairingHandler::NotPaired); + setInternalPairStatus(NotPaired); } } @@ -85,9 +77,9 @@ void LanPairingHandler::packageReceived(const NetworkPackage& np) if (QCA::RSAPublicKey::fromPEM(keyString).isNull()) { if (isPairRequested()) { - setPairStatus(PairStatus::NotPaired); + setInternalPairStatus(NotPaired); } - Q_EMIT pairingFailed(i18n("Received incorrect key")); + Q_EMIT pairingError(i18n("Received incorrect key")); return; } @@ -105,9 +97,8 @@ void LanPairingHandler::packageReceived(const NetworkPackage& np) return; } - //Daemon::instance()->requestPairing(m_device); - //m_pairStatus = PairStatus::RequestedByPeer; - setPairStatus(PairStatus::RequestedByPeer); + Daemon::instance()->requestPairing(this); + setInternalPairStatus(RequestedByPeer); } } else { //wantsPair == false @@ -115,27 +106,27 @@ void LanPairingHandler::packageReceived(const NetworkPackage& np) qCDebug(KDECONNECT_CORE) << "Unpair request"; if (isPairRequested()) { - Q_EMIT pairingFailed(i18n("Canceled by other peer")); + Q_EMIT pairingError(i18n("Canceled by other peer")); } - setPairStatus(PairStatus::NotPaired); + setInternalPairStatus(NotPaired); } } bool LanPairingHandler::requestPairing() { - switch (pairStatus()) { - case PairStatus::Paired: - Q_EMIT pairingFailed(i18n(deviceLink()->name().append(" : Already paired").toLatin1().data())); + switch (m_status) { + case Paired: + Q_EMIT pairingError(i18n(deviceLink()->name().append(" : Already paired").toLatin1().data())); return false; - case PairStatus::Requested: - Q_EMIT pairingFailed(i18n(deviceLink()->name().append(" : Pairing already requested for this device").toLatin1().data())); + case Requested: + Q_EMIT pairingError(i18n(deviceLink()->name().append(" : Pairing already requested for this device").toLatin1().data())); return false; - case PairStatus::RequestedByPeer: + case RequestedByPeer: qCDebug(KDECONNECT_CORE) << deviceLink()->name() << " : Pairing already started by the other end, accepting their request."; acceptPairing(); return false; - case PairStatus::NotPaired: + case NotPaired: ; } @@ -144,7 +135,7 @@ bool LanPairingHandler::requestPairing() bool success; success = deviceLink()->sendPackage(np); if (success) { - setPairStatus(PairStatus::Requested); + setInternalPairStatus(Requested); m_pairingTimeout.start(); } return success; @@ -158,7 +149,7 @@ bool LanPairingHandler::acceptPairing() bool success; success = deviceLink()->sendPackage(np); if (success) { - setPairStatus(PairStatus::Paired); + setInternalPairStatus(Paired); } return success; } @@ -169,7 +160,7 @@ void LanPairingHandler::rejectPairing() np.set("pair", false); np.set("link", deviceLink()->name()); deviceLink()->sendPackage(np); - setPairStatus(PairStatus::NotPaired); + setInternalPairStatus(NotPaired); } void LanPairingHandler::unpair() { @@ -177,7 +168,7 @@ void LanPairingHandler::unpair() { np.set("pair", false); np.set("link", deviceLink()->name()); deviceLink()->sendPackage(np); - setPairStatus(PairStatus::NotPaired); + setInternalPairStatus(NotPaired); } void LanPairingHandler::pairingTimeout() @@ -186,6 +177,16 @@ void LanPairingHandler::pairingTimeout() np.set("pair", false); np.set("name", deviceLink()->name()); deviceLink()->sendPackage(np); - setPairStatus(PairStatus::NotPaired); //Will emit the change as well - Q_EMIT pairingFailed(i18n("Timed out")); + setInternalPairStatus(NotPaired); //Will emit the change as well + Q_EMIT pairingError(i18n("Timed out")); +} + +void LanPairingHandler::setInternalPairStatus(LanPairingHandler::InternalPairStatus status) +{ + m_status = status; + if (status == Paired) { + deviceLink()->setPairStatus(DeviceLink::Paired); + } else { + deviceLink()->setPairStatus(DeviceLink::NotPaired); + } } diff --git a/core/backends/lan/lanpairinghandler.h b/core/backends/lan/lanpairinghandler.h index d723634a0..a088bb348 100644 --- a/core/backends/lan/lanpairinghandler.h +++ b/core/backends/lan/lanpairinghandler.h @@ -30,6 +30,14 @@ class LanPairingHandler : public PairingHandler { public: + + enum InternalPairStatus { + NotPaired, + Requested, + RequestedByPeer, + Paired, + }; + LanPairingHandler(const QString& deviceId); virtual ~LanPairingHandler() { } @@ -40,15 +48,19 @@ public: virtual void rejectPairing() Q_DECL_OVERRIDE; virtual void unpair() Q_DECL_OVERRIDE; + bool isPairRequested() const { return m_status == Requested; } + bool isPaired() const { return m_status == Paired; } + private Q_SLOTS: - virtual void pairingTimeout(); + void pairingTimeout(); protected: + void setInternalPairStatus(InternalPairStatus status); + QTimer m_pairingTimeout; QString m_deviceId; - QCA::PublicKey m_publicKey; - QSslCertificate m_certificate; + InternalPairStatus m_status; }; diff --git a/core/backends/linkprovider.h b/core/backends/linkprovider.h index 4b1cf831b..dee358910 100644 --- a/core/backends/linkprovider.h +++ b/core/backends/linkprovider.h @@ -30,7 +30,7 @@ class DeviceLink; -class LinkProvider +class KDECONNECTCORE_EXPORT LinkProvider : public QObject { Q_OBJECT diff --git a/core/backends/loopback/CMakeLists.txt b/core/backends/loopback/CMakeLists.txt index f90f00dee..dd9f59a31 100644 --- a/core/backends/loopback/CMakeLists.txt +++ b/core/backends/loopback/CMakeLists.txt @@ -4,7 +4,7 @@ set(backends_kdeconnect_SRCS backends/loopback/loopbacklinkprovider.cpp backends/loopback/loopbackdevicelink.cpp - backends/loopback/loopbackpairinghandler.cpp +# backends/loopback/loopbackpairinghandler.cpp PARENT_SCOPE ) diff --git a/core/backends/loopback/loopbackdevicelink.cpp b/core/backends/loopback/loopbackdevicelink.cpp index fefaa5d65..ef9a017a9 100644 --- a/core/backends/loopback/loopbackdevicelink.cpp +++ b/core/backends/loopback/loopbackdevicelink.cpp @@ -34,10 +34,6 @@ QString LoopbackDeviceLink::name() return "LoopbackLink"; // Should be similar to android } -PairingHandler* LoopbackDeviceLink::createPairingHandler(Device *device) -{ - return new LoopbackPairingHandler(device->id()); -} bool LoopbackDeviceLink::sendPackageEncrypted(NetworkPackage& input) { return sendPackage(input); diff --git a/core/backends/loopback/loopbackdevicelink.h b/core/backends/loopback/loopbackdevicelink.h index 97864e7e5..b1e4e832f 100644 --- a/core/backends/loopback/loopbackdevicelink.h +++ b/core/backends/loopback/loopbackdevicelink.h @@ -33,10 +33,11 @@ public: LoopbackDeviceLink(const QString& d, LoopbackLinkProvider* a); virtual QString name() override; - virtual PairingHandler* createPairingHandler(Device* device) override; virtual bool sendPackage(NetworkPackage& np) override; virtual bool sendPackageEncrypted(NetworkPackage& np) override; + virtual void requestPairing() override {} + virtual void unpair() override {} }; #endif diff --git a/core/backends/loopback/loopbackpairinghandler.cpp b/core/backends/loopback/loopbackpairinghandler.cpp index 7ff8117a5..a1bdfe04f 100644 --- a/core/backends/loopback/loopbackpairinghandler.cpp +++ b/core/backends/loopback/loopbackpairinghandler.cpp @@ -39,10 +39,10 @@ bool LoopbackPairingHandler::requestPairing() case PairStatus::Paired: Q_EMIT pairingFailed(deviceLink()->name().append(" : Already paired").toLatin1().data()); return false; - case PairStatus ::Requested: + case PairStatus::Requested: Q_EMIT pairingFailed(deviceLink()->name().append(" : Pairing already requested for this device").toLatin1().data()); return false; - case PairStatus ::RequestedByPeer: + case PairStatus::RequestedByPeer: qCDebug(KDECONNECT_CORE) << deviceLink()->name() << " : Pairing already started by the other end, accepting their request."; acceptPairing(); return false; diff --git a/core/backends/pairinghandler.cpp b/core/backends/pairinghandler.cpp index 2633f5324..f280742e9 100644 --- a/core/backends/pairinghandler.cpp +++ b/core/backends/pairinghandler.cpp @@ -1,5 +1,5 @@ /** - * Copyright 2015 Vineet Garg + * Copyright 2015 Albert Vaca Cintora * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -20,15 +20,16 @@ #include "pairinghandler.h" -PairingHandler::PairingHandler() - : m_deviceLink(nullptr) - , m_pairStatus(NotPaired) +PairingHandler::PairingHandler(DeviceLink* parent) + : QObject(parent) + , m_deviceLink(parent) { } void PairingHandler::setDeviceLink(DeviceLink *dl) { + setParent(dl); m_deviceLink = dl; } @@ -37,26 +38,3 @@ DeviceLink* PairingHandler::deviceLink() const return m_deviceLink; } -void PairingHandler::linkDestroyed(QObject* o) -{ - DeviceLink* dl = static_cast(o); - if (dl == m_deviceLink) { // Check if same link is destroyed - m_deviceLink = Q_NULLPTR; - Q_EMIT linkNull(); - } -} - -void PairingHandler::setPairStatus(PairingHandler::PairStatus status) -{ - if (m_pairStatus != status) { - PairStatus oldStatus = m_pairStatus; - m_pairStatus = status; - Q_EMIT pairStatusChanged(status, oldStatus); - } -} - -PairingHandler::PairStatus PairingHandler::pairStatus() const -{ - return m_pairStatus; -} - diff --git a/core/backends/pairinghandler.h b/core/backends/pairinghandler.h index 0caf5c8aa..1aac977aa 100644 --- a/core/backends/pairinghandler.h +++ b/core/backends/pairinghandler.h @@ -37,56 +37,31 @@ * After that if any one of the link is paired, then we can say that device is paired, so new link will pair automatically */ -class PairingHandler : public QObject +class KDECONNECTCORE_EXPORT PairingHandler : public QObject { Q_OBJECT public: - - //TODO: Can we simplify this to just Paired/NotPaired, and leave the detailed status as an backend-specific thing? - enum PairStatus { - NotPaired, - Requested, - RequestedByPeer, - Paired, - }; - - PairingHandler(); + PairingHandler(DeviceLink* parent = 0); virtual ~PairingHandler() { } + DeviceLink* deviceLink() const; void setDeviceLink(DeviceLink* dl); - bool isPaired() const { return m_pairStatus == PairStatus::Paired; } - bool isPairRequested() const { return m_pairStatus == PairStatus::Requested; } - virtual void createPairPackage(NetworkPackage& np) = 0; virtual void packageReceived(const NetworkPackage& np) = 0; + virtual void unpair() = 0; + +public Q_SLOTS: virtual bool requestPairing() = 0; virtual bool acceptPairing() = 0; virtual void rejectPairing() = 0; - virtual void unpair() = 0; - -protected: - DeviceLink* deviceLink() const; - void setPairStatus(PairStatus status); - PairStatus pairStatus() const; - -public Q_SLOTS: - void linkDestroyed(QObject*); - virtual void pairingTimeout() = 0; Q_SIGNALS: - void pairStatusChanged(PairStatus status, PairStatus previousStatus); + void pairingError(const QString& errorMessage); private: DeviceLink* m_deviceLink; // We keep the latest link here, if this is destroyed without new link, linkDestroyed is emitted and device will destroy pairing handler - PairStatus m_pairStatus; - -Q_SIGNALS: - void pairingDone(); - void unpairingDone(); - void pairingFailed(const QString& error); - void linkNull(); }; diff --git a/core/daemon.cpp b/core/daemon.cpp index 0b97fddad..0b13b2db5 100644 --- a/core/daemon.cpp +++ b/core/daemon.cpp @@ -123,7 +123,7 @@ void Daemon::removeDevice(Device* device) void Daemon::cleanDevices() { Q_FOREACH(Device* device, d->mDevices) { - if (device->pairStatus() == PairingHandler::NotPaired && device->connectionSource() == DeviceLink::ConnectionStarted::Remotely) { + if (!device->isTrusted() && device->connectionSource() == DeviceLink::ConnectionStarted::Remotely) { removeDevice(device); } } @@ -148,12 +148,12 @@ Device *Daemon::getDevice(QString deviceId) { return Q_NULLPTR; } -QStringList Daemon::devices(bool onlyReachable, bool onlyPaired) const +QStringList Daemon::devices(bool onlyReachable, bool onlyTrusted) const { QStringList ret; Q_FOREACH(Device* device, d->mDevices) { if (onlyReachable && !device->isReachable()) continue; - if (onlyPaired && !device->isPaired()) continue; + if (onlyTrusted && !device->isTrusted()) continue; ret.append(device->id()); } return ret; @@ -179,7 +179,7 @@ void Daemon::onNewDeviceLink(const NetworkPackage& identityPackage, DeviceLink* //we discard the connections that we created but it's not paired. //we keep the remotely initiated ones, since the remotes require them - if (!isDiscoveringDevices() && !device->isPaired() && dl->connectionSource() == DeviceLink::ConnectionStarted::Locally) { + if (!isDiscoveringDevices() && !device->isTrusted() && dl->connectionSource() == DeviceLink::ConnectionStarted::Locally) { device->deleteLater(); } else { connect(device, SIGNAL(reachableStatusChanged()), this, SLOT(onDeviceStatusChanged())); @@ -197,7 +197,7 @@ void Daemon::onDeviceStatusChanged() //qCDebug(KDECONNECT_CORE) << "Device" << device->name() << "status changed. Reachable:" << device->isReachable() << ". Paired: " << device->isPaired(); - if (!device->isReachable() && !device->isPaired()) { + if (!device->isReachable() && !device->isTrusted()) { //qCDebug(KDECONNECT_CORE) << "Destroying device" << device->name(); removeDevice(device); } else { diff --git a/core/daemon.h b/core/daemon.h index 66b536473..908c1e3c1 100644 --- a/core/daemon.h +++ b/core/daemon.h @@ -53,7 +53,7 @@ public: QList devicesList() const; - virtual void requestPairing(Device *d) = 0; + virtual void requestPairing(PairingHandler *d) = 0; virtual void reportError(const QString &title, const QString &description) = 0; virtual QNetworkAccessManager* networkAccessManager(); diff --git a/core/device.cpp b/core/device.cpp index a37e8eb61..95aed4850 100644 --- a/core/device.cpp +++ b/core/device.cpp @@ -76,7 +76,6 @@ Device::Device(QObject* parent, const NetworkPackage& identityPackage, DeviceLin Device::~Device() { - qDeleteAll(m_pairingHandlers); } bool Device::hasPlugin(const QString& name) const @@ -98,7 +97,7 @@ void Device::reloadPlugins() QSet supportedOutgoingInterfaces; QStringList unsupportedPlugins; - if (isPaired() && isReachable()) { //Do not load any plugin for unpaired devices, nor useless loading them for unreachable devices + if (isTrusted() && isReachable()) { //Do not load any plugin for unpaired devices, nor useless loading them for unreachable devices KConfigGroup pluginStates = KSharedConfig::openConfig(pluginsConfigFile())->group("Plugins"); @@ -169,7 +168,7 @@ void Device::reloadPlugins() } Q_EMIT pluginsChanged(); - if (capabilitiesChanged && isReachable() && isPaired()) + if (capabilitiesChanged && isReachable() && isTrusted()) { NetworkPackage np(PACKAGE_TYPE_CAPABILITIES); np.set("IncomingCapabilities", newSupportedIncomingInterfaces); @@ -183,59 +182,50 @@ QString Device::pluginsConfigFile() const return KdeConnectConfig::instance()->deviceConfigDir(id()).absoluteFilePath("config"); } -bool Device::isPairRequested() const -{ - bool isPairRequested = false; - Q_FOREACH(PairingHandler* ph, m_pairingHandlers) { - isPairRequested = isPairRequested || ph->isPairRequested(); - } - return isPairRequested; -} - void Device::requestPair() { - if (isPaired()) { - Q_EMIT pairingFailed(i18n("Already paired")); + if (isTrusted()) { + Q_EMIT pairingError(i18n("Already paired")); return; } if (!isReachable()) { - Q_EMIT pairingFailed(i18n("Device not reachable")); + Q_EMIT pairingError(i18n("Device not reachable")); return; } - bool success = false; - Q_FOREACH(PairingHandler* ph, m_pairingHandlers.values()) { - success = success || ph->requestPairing(); // If one of many pairing handlers can successfully request pairing, consider it success - } - if (!success) { - Q_EMIT pairingFailed(i18n("Error contacting device")); - return; + Q_FOREACH(DeviceLink* dl, m_deviceLinks) { + dl->requestPairing(); } } void Device::unpair() { - Q_FOREACH(PairingHandler* ph, m_pairingHandlers.values()) { - ph->unpair(); + Q_FOREACH(DeviceLink* dl, m_deviceLinks) { + dl->unpair(); } + KdeConnectConfig::instance()->removeTrustedDevice(id()); } -void Device::pairStatusChanged(PairingHandler::PairStatus status, PairingHandler::PairStatus oldStatus) +void Device::pairStatusChanged(DeviceLink::PairStatus status) { - if (oldStatus == PairingHandler::Paired && status == PairingHandler::NotPaired) { - KdeConnectConfig::instance()->removeTrustedDevice(m_deviceId); - Q_FOREACH(PairingHandler* ph, m_pairingHandlers.values()) { - ph->unpair(); + if (status == DeviceLink::NotPaired) { + KdeConnectConfig::instance()->removeTrustedDevice(id()); + + Q_FOREACH(DeviceLink* dl, m_deviceLinks) { + if (dl != sender()) { + dl->unpair(); + } } + } else { + KdeConnectConfig::instance()->addTrustedDevice(id(), name(), type()); } - if (oldStatus == PairingHandler::NotPaired && status == PairingHandler::Paired) { - reloadPlugins(); //Will unload the plugins - } - - Q_EMIT pairingChanged(status == PairingHandler::Paired); + reloadPlugins(); //Will load/unload plugins + bool isTrusted = (status == DeviceLink::Paired); + Q_EMIT trustedChanged(isTrusted? Trusted : NotTrusted); + Q_ASSERT(isTrusted == this->isTrusted()); } static bool lessThan(DeviceLink* p1, DeviceLink* p2) @@ -281,16 +271,8 @@ void Device::addLink(const NetworkPackage& identityPackage, DeviceLink* link) } } - // One pairing handler per type of device link, so check if there is already a pairing handler of same type, if not add it to the list - if (!m_pairingHandlers.contains(link->name())) { - PairingHandler* pairingHandler = link->createPairingHandler(this); - m_pairingHandlers.insert(link->name(), pairingHandler); - connect(m_pairingHandlers[link->name()], SIGNAL(linkNull()), this, SLOT(destroyPairingHandler())); - connect(m_pairingHandlers[link->name()], SIGNAL(pairStatusChanged(PairStatus, PairStatus)), this, SLOT(pairStatusChanged(PairStatus, PairStatus))); - connect(m_pairingHandlers[link->name()], SIGNAL(pairingFailed(const QString&)), this, SIGNAL(pairingFailed(const QString&))); - } - m_pairingHandlers[link->name()]->setDeviceLink(link); - connect(link, SIGNAL(destroyed(QObject*)), m_pairingHandlers[link->name()], SLOT(linkDestroyed(QObject*))); + connect(link, SIGNAL(pairStatusChanged(PairStatus)), this, SLOT(pairStatusChanged(PairStatus, PairStatus))); + connect(link, SIGNAL(pairingFailed(const QString&)), this, SIGNAL(pairingFailed(const QString&))); } void Device::linkDestroyed(QObject* o) @@ -300,7 +282,7 @@ void Device::linkDestroyed(QObject* o) void Device::removeLink(DeviceLink* link) { - m_deviceLinks.removeOne(link); + m_deviceLinks.removeAll(link); //qCDebug(KDECONNECT_CORE) << "RemoveLink" << m_deviceLinks.size() << "links remaining"; @@ -310,16 +292,9 @@ void Device::removeLink(DeviceLink* link) } } -void Device::destroyPairingHandler() -{ - PairingHandler* ph = qobject_cast(sender()); - m_pairingHandlers.remove(m_pairingHandlers.key(ph)); - delete ph; -} - bool Device::sendPackage(NetworkPackage& np) { - if (np.type() != PACKAGE_TYPE_PAIR && isPaired()) { + if (np.type() != PACKAGE_TYPE_PAIR && isTrusted()) { Q_FOREACH(DeviceLink* dl, m_deviceLinks) { if (dl->sendPackageEncrypted(np)) return true; } @@ -335,14 +310,8 @@ bool Device::sendPackage(NetworkPackage& np) void Device::privateReceivedPackage(const NetworkPackage& np) { - if (np.type() == PACKAGE_TYPE_PAIR) { - - // If PACKAGE_TYPE_PAIR, send it to pairing handlers without thinking - Q_FOREACH(PairingHandler* ph, m_pairingHandlers) { - ph->packageReceived(np); - } - - } else if (np.type() == PACKAGE_TYPE_CAPABILITIES) { + Q_ASSERT(np.type() != PACKAGE_TYPE_PAIR); + if (np.type() == PACKAGE_TYPE_CAPABILITIES) { QSet newIncomingCapabilities = np.get("IncomingCapabilities", QStringList()).toSet(); QSet newOutgoingCapabilities = np.get("OutgoingCapabilities", QStringList()).toSet(); @@ -351,7 +320,7 @@ void Device::privateReceivedPackage(const NetworkPackage& np) m_outgoingCapabilities = newOutgoingCapabilities; reloadPlugins(); } - } else if (isPaired()) { + } else if (isTrusted()) { QList plugins = m_pluginsByIncomingInterface.values(np.type()); foreach(KdeConnectPlugin* plugin, plugins) { plugin->receivePackage(np); @@ -363,38 +332,11 @@ void Device::privateReceivedPackage(const NetworkPackage& np) } -void Device::rejectPairing() +bool Device::isTrusted() const { - qCDebug(KDECONNECT_CORE) << "Rejected pairing"; - - Q_FOREACH(PairingHandler* ph, m_pairingHandlers.values()) { - ph->rejectPairing(); - } - - Q_EMIT pairingFailed(i18n("Canceled by the user")); - + return KdeConnectConfig::instance()->trustedDevices().contains(id()); } -void Device::acceptPairing() -{ - qCDebug(KDECONNECT_CORE) << "Accepted pairing"; - - bool success = false; - Q_FOREACH(PairingHandler* ph, m_pairingHandlers) { - success = success || ph->acceptPairing(); - } - -} - -bool Device::isPaired() const -{ - Q_FOREACH(PairingHandler* ph, m_pairingHandlers) { - if (ph->isPaired()) return true; - } - return false; -} - - DeviceLink::ConnectionStarted Device::connectionSource() const { DeviceLink::ConnectionStarted ret = DeviceLink::Remotely; @@ -434,7 +376,7 @@ QString Device::type2str(Device::DeviceType deviceType) { QString Device::statusIconName() const { - return iconForStatus(isReachable(), isPaired()); + return iconForStatus(isReachable(), isTrusted()); } QString Device::iconName() const @@ -443,7 +385,7 @@ QString Device::iconName() const return iconForStatus(true, false); } -QString Device::iconForStatus(bool reachable, bool paired) const +QString Device::iconForStatus(bool reachable, bool trusted) const { Device::DeviceType deviceType = m_deviceType; if (deviceType == Device::Unknown) { @@ -452,7 +394,7 @@ QString Device::iconForStatus(bool reachable, bool paired) const deviceType = Device::Device::Laptop; // We don't have desktop icon yet } - QString status = (reachable? (paired? QStringLiteral("connected") : QStringLiteral("disconnected")) : QStringLiteral("trusted")); + QString status = (reachable? (trusted? QStringLiteral("connected") : QStringLiteral("disconnected")) : QStringLiteral("trusted")); QString type = type2str(deviceType); return type+'-'+status; @@ -466,11 +408,6 @@ void Device::setName(const QString &name) } } -PairingHandler::PairStatus Device::pairStatus() const -{ - return isPaired()? PairingHandler::Paired : PairingHandler::NotPaired; -} - KdeConnectPlugin* Device::plugin(const QString& pluginName) const { return m_plugins[pluginName]; diff --git a/core/device.h b/core/device.h index 26fc97dc6..8f550d679 100644 --- a/core/device.h +++ b/core/device.h @@ -30,7 +30,6 @@ #include #include -#include "backends/pairinghandler.h" #include "networkpackage.h" #include "backends/devicelink.h" @@ -47,7 +46,7 @@ class KDECONNECTCORE_EXPORT Device Q_PROPERTY(QString iconName READ iconName CONSTANT) Q_PROPERTY(QString statusIconName READ statusIconName) Q_PROPERTY(bool isReachable READ isReachable NOTIFY reachableStatusChanged) - Q_PROPERTY(bool isPaired READ isPaired NOTIFY pairingChanged) + Q_PROPERTY(bool isTrusted READ isTrusted NOTIFY trustedChanged) Q_PROPERTY(QStringList unsupportedPlugins READ unsupportedPlugins NOTIFY pluginsChanged) public: @@ -60,6 +59,11 @@ public: Tablet, }; + enum TrustStatus { + NotTrusted, + Trusted + }; + /** * Restores the @p device from the saved configuration * @@ -89,8 +93,7 @@ public: void addLink(const NetworkPackage& identityPackage, DeviceLink*); void removeLink(DeviceLink*); - Q_SCRIPTABLE bool isPaired() const; - Q_SCRIPTABLE bool isPairRequested() const; + Q_SCRIPTABLE bool isTrusted() const; Q_SCRIPTABLE QStringList availableLinks() const; bool isReachable() const { return !m_deviceLinks.isEmpty(); } @@ -104,8 +107,6 @@ public: void setPluginEnabled(const QString& pluginName, bool enabled); bool isPluginEnabled(const QString& pluginName) const; - PairingHandler::PairStatus pairStatus() const; - DeviceLink::ConnectionStarted connectionSource() const; public Q_SLOTS: @@ -114,25 +115,20 @@ public Q_SLOTS: //Dbus operations public Q_SLOTS: - Q_SCRIPTABLE void requestPair(); - Q_SCRIPTABLE void unpair(); - Q_SCRIPTABLE void reloadPlugins(); //From kconf - void acceptPairing(); - void rejectPairing(); + Q_SCRIPTABLE void requestPair(); //to all links + Q_SCRIPTABLE void unpair(); //from all links + Q_SCRIPTABLE void reloadPlugins(); //from kconf private Q_SLOTS: void privateReceivedPackage(const NetworkPackage& np); void linkDestroyed(QObject* o); - void destroyPairingHandler(); - - void pairStatusChanged(PairingHandler::PairStatus current, PairingHandler::PairStatus old); - + void pairStatusChanged(DeviceLink::PairStatus current); Q_SIGNALS: Q_SCRIPTABLE void pluginsChanged(); Q_SCRIPTABLE void reachableStatusChanged(); - Q_SCRIPTABLE void pairingChanged(bool paired); - Q_SCRIPTABLE void pairingFailed(const QString& error); + Q_SCRIPTABLE void trustedChanged(bool trusted); + Q_SCRIPTABLE void pairingError(const QString& error); Q_SCRIPTABLE void nameChanged(const QString& name); private: //Methods @@ -150,10 +146,10 @@ private: //Fields (TODO: dPointer!) QVector m_deviceLinks; QHash m_plugins; - QMap m_pairingHandlers; + + //Capabilities stuff QMultiMap m_pluginsByIncomingInterface; QMultiMap m_pluginsByOutgoingInterface; - QSet m_incomingCapabilities; QSet m_outgoingCapabilities; QStringList m_supportedIncomingInterfaces; diff --git a/daemon/kdeconnectd.cpp b/daemon/kdeconnectd.cpp index 1b754698e..d612c40b4 100644 --- a/daemon/kdeconnectd.cpp +++ b/daemon/kdeconnectd.cpp @@ -32,6 +32,7 @@ #include "core/daemon.h" #include "core/device.h" +#include "core/backends/pairinghandler.h" #include "kdeconnect-version.h" #ifdef HAVE_TELEPATHY @@ -88,16 +89,16 @@ public: , m_nam(Q_NULLPTR) {} - void requestPairing(Device* d) Q_DECL_OVERRIDE + void requestPairing(PairingHandler* d) Q_DECL_OVERRIDE { KNotification* notification = new KNotification("pairingRequest"); notification->setIconName(QStringLiteral("dialog-information")); notification->setComponentName("kdeconnect"); - notification->setText(i18n("Pairing request from %1", d->name())); + notification->setText(i18n("Pairing request from %1", d->deviceLink()->name())); notification->setActions(QStringList() << i18n("Accept") << i18n("Reject")); - connect(notification, &KNotification::ignored, d, &Device::rejectPairing); - connect(notification, &KNotification::action1Activated, d, &Device::acceptPairing); - connect(notification, &KNotification::action2Activated, d, &Device::rejectPairing); + connect(notification, &KNotification::ignored, d, &PairingHandler::rejectPairing); + connect(notification, &KNotification::action1Activated, d, &PairingHandler::acceptPairing); + connect(notification, &KNotification::action2Activated, d, &PairingHandler::rejectPairing); notification->sendEvent(); } diff --git a/interfaces/dbusinterfaces.cpp b/interfaces/dbusinterfaces.cpp index d0883f8be..c37616a45 100644 --- a/interfaces/dbusinterfaces.cpp +++ b/interfaces/dbusinterfaces.cpp @@ -44,7 +44,7 @@ DeviceDbusInterface::DeviceDbusInterface(const QString& id, QObject* parent) : OrgKdeKdeconnectDeviceInterface(DaemonDbusInterface::activatedService(), "/modules/kdeconnect/devices/"+id, QDBusConnection::sessionBus(), parent) , m_id(id) { - connect(this, &OrgKdeKdeconnectDeviceInterface::pairingChanged, this, &DeviceDbusInterface::pairingChangedProxy); + connect(this, &OrgKdeKdeconnectDeviceInterface::trustedChanged, this, &DeviceDbusInterface::trustedChangedProxy); } DeviceDbusInterface::~DeviceDbusInterface() diff --git a/interfaces/dbusinterfaces.h b/interfaces/dbusinterfaces.h index b5705e684..9f7365598 100644 --- a/interfaces/dbusinterfaces.h +++ b/interfaces/dbusinterfaces.h @@ -58,7 +58,7 @@ class KDECONNECTINTERFACES_EXPORT DeviceDbusInterface Q_OBJECT // TODO: Workaround because OrgKdeKdeconnectDeviceInterface is not generating // the signals for the properties - Q_PROPERTY(bool isPaired READ isPaired NOTIFY pairingChangedProxy) + Q_PROPERTY(bool isTrusted READ isTrusted NOTIFY trustedChangedProxy) public: explicit DeviceDbusInterface(const QString& deviceId, QObject* parent = nullptr); @@ -68,7 +68,7 @@ public: Q_SCRIPTABLE void pluginCall(const QString &plugin, const QString &method); Q_SIGNALS: - void pairingChangedProxy(bool paired); + void trustedChangedProxy(bool paired); private: const QString m_id; diff --git a/interfaces/devicesmodel.cpp b/interfaces/devicesmodel.cpp index 7b0fdbb77..83e7b5805 100644 --- a/interfaces/devicesmodel.cpp +++ b/interfaces/devicesmodel.cpp @@ -105,7 +105,7 @@ void DevicesModel::deviceAdded(const QString& id) bool onlyPaired = (m_displayFilter & StatusFilterFlag::Paired); bool onlyReachable = (m_displayFilter & StatusFilterFlag::Reachable); - if ((onlyReachable && !dev->isReachable()) || (onlyPaired && !dev->isPaired())) { + if ((onlyReachable && !dev->isReachable()) || (onlyPaired && !dev->isTrusted())) { delete dev; return; } @@ -255,16 +255,16 @@ QVariant DevicesModel::data(const QModelIndex& index, int role) const case NameModelRole: return device->name(); case Qt::ToolTipRole: { - bool paired = device->isPaired(); + bool trusted = device->isTrusted(); bool reachable = device->isReachable(); - QString status = reachable? (paired? i18n("Device trusted and connected") : i18n("Device not trusted")) : i18n("Device disconnected"); + QString status = reachable? (trusted? i18n("Device trusted and connected") : i18n("Device not trusted")) : i18n("Device disconnected"); return status; } case StatusModelRole: { int status = StatusFilterFlag::NoFilter; if (device->isReachable()) { status |= StatusFilterFlag::Reachable; - if (device->isPaired()) status |= StatusFilterFlag::Paired; + if (device->isTrusted()) status |= StatusFilterFlag::Paired; } return status; } diff --git a/kcm/kcm.cpp b/kcm/kcm.cpp index cae6cdcb0..f62cdfa3a 100644 --- a/kcm/kcm.cpp +++ b/kcm/kcm.cpp @@ -180,22 +180,15 @@ void KdeConnectKcm::deviceSelected(const QModelIndex& current) } kcmUi->messages->setVisible(false); - if (currentDevice->isPairRequested()) { - kcmUi->progressBar->setVisible(true); - kcmUi->unpair_button->setVisible(false); + kcmUi->progressBar->setVisible(false); + if (currentDevice->isTrusted()) { + kcmUi->unpair_button->setVisible(true); kcmUi->pair_button->setVisible(false); - kcmUi->ping_button->setVisible(false); + kcmUi->ping_button->setVisible(true); } else { - kcmUi->progressBar->setVisible(false); - if (currentDevice->isPaired()) { - kcmUi->unpair_button->setVisible(true); - kcmUi->pair_button->setVisible(false); - kcmUi->ping_button->setVisible(true); - } else { - kcmUi->unpair_button->setVisible(false); - kcmUi->pair_button->setVisible(true); - kcmUi->ping_button->setVisible(false); - } + kcmUi->unpair_button->setVisible(false); + kcmUi->pair_button->setVisible(true); + kcmUi->ping_button->setVisible(false); } resetDeviceView(); @@ -223,7 +216,7 @@ void KdeConnectKcm::resetDeviceView() kcmUi->pluginSelector->setConfigurationArguments(QStringList(currentDevice->id())); kcmUi->name_label->setText(currentDevice->name()); - kcmUi->status_label->setText(currentDevice->isPaired()? i18n("(paired)") : i18n("(unpaired)")); + kcmUi->status_label->setText(currentDevice->isTrusted()? i18n("(trusted)") : i18n("(not trusted)")); const QList pluginInfo = KPluginInfo::fromMetaData(KPluginLoader::findPlugins("kdeconnect/")); QList availablePluginInfo; @@ -286,7 +279,7 @@ void KdeConnectKcm::pairingChanged(bool paired) kcmUi->pair_button->setVisible(!paired); kcmUi->unpair_button->setVisible(paired); - kcmUi->progressBar->setVisible(senderDevice->isPairRequested()); + kcmUi->progressBar->setVisible(false); kcmUi->ping_button->setVisible(paired); kcmUi->status_label->setText(paired ? i18n("(paired)") : i18n("(unpaired)")); } diff --git a/tests/devicetest.cpp b/tests/devicetest.cpp index f7b9d27a5..716911bf8 100644 --- a/tests/devicetest.cpp +++ b/tests/devicetest.cpp @@ -69,8 +69,7 @@ void DeviceTest::testPairedDevice() QCOMPARE(device.name(), deviceName); QCOMPARE(device.type(), deviceType); - QCOMPARE(device.isPaired(), true); - QCOMPARE(device.isPairRequested(), false); + QCOMPARE(device.isTrusted(), true); QCOMPARE(device.isReachable(), false); @@ -90,7 +89,7 @@ void DeviceTest::testPairedDevice() QCOMPARE(device.availableLinks().contains(linkProvider.name()), false); device.unpair(); - QCOMPARE(device.isPaired(), false); + QCOMPARE(device.isTrusted(), false); } @@ -106,8 +105,7 @@ void DeviceTest::testUnpairedDevice() QCOMPARE(device.name(), deviceName); QCOMPARE(device.type(), deviceType); - QCOMPARE(device.isPaired(), false); - QCOMPARE(device.isPairRequested(), false); + QCOMPARE(device.isTrusted(), false); QCOMPARE(device.isReachable(), true); QCOMPARE(device.availableLinks().contains(linkProvider.name()), true); diff --git a/tests/pluginloadtest.cpp b/tests/pluginloadtest.cpp index 259a47ed8..b70eea222 100644 --- a/tests/pluginloadtest.cpp +++ b/tests/pluginloadtest.cpp @@ -31,6 +31,7 @@ #include "core/daemon.h" #include "core/device.h" #include "core/kdeconnectplugin.h" +#include #include "kdeconnect-version.h" class TestDaemon : public Daemon @@ -43,7 +44,7 @@ public: { } - void requestPairing(Device* d) Q_DECL_OVERRIDE + void requestPairing(PairingHandler* d) Q_DECL_OVERRIDE { d->acceptPairing(); } @@ -88,7 +89,7 @@ class PluginLoadTest : public QObject } QVERIFY(d); - QVERIFY(d->isPaired()); + QVERIFY(d->isTrusted()); QVERIFY(d->isReachable()); d->setPluginEnabled("kdeconnect_mousepad", false); diff --git a/tests/sendfiletest.cpp b/tests/sendfiletest.cpp index 015818b36..3402fe04d 100644 --- a/tests/sendfiletest.cpp +++ b/tests/sendfiletest.cpp @@ -31,6 +31,7 @@ #include "core/daemon.h" #include "core/device.h" #include "core/kdeconnectplugin.h" +#include #include "kdeconnect-version.h" class TestDaemon : public Daemon @@ -43,7 +44,7 @@ public: { } - void requestPairing(Device* d) Q_DECL_OVERRIDE + void requestPairing(PairingHandler* d) Q_DECL_OVERRIDE { d->acceptPairing(); } @@ -84,7 +85,7 @@ class TestSendFile : public QObject } QVERIFY(d); QCOMPARE(d->isReachable(), true); - QCOMPARE(d->isPaired(), true); + QCOMPARE(d->isTrusted(), true); QByteArray content("12312312312313213123213123");