diff --git a/app/qml/DevicePage.qml b/app/qml/DevicePage.qml index 95a94c75e..21e7ccee8 100644 --- a/app/qml/DevicePage.qml +++ b/app/qml/DevicePage.qml @@ -21,12 +21,12 @@ Kirigami.ScrollablePage { iconName:"network-disconnect" onTriggered: root.currentDevice.unpair() text: i18nd("kdeconnect-app", "Unpair") - visible: root.currentDevice.isTrusted + visible: root.currentDevice.isPaired }, Kirigami.Action { iconName:"hands-free" text: i18nd("kdeconnect-app", "Send Ping") - visible: root.currentDevice.isTrusted && root.currentDevice.isReachable + visible: root.currentDevice.isPaired && root.currentDevice.isReachable onTriggered: { root.currentDevice.pluginCall("ping", "sendPing"); } @@ -34,7 +34,7 @@ Kirigami.ScrollablePage { Kirigami.Action { iconName: "settings-configure" text: i18n("Plugin Settings") - visible: root.currentDevice.isTrusted && root.currentDevice.isReachable + visible: root.currentDevice.isPaired && root.currentDevice.isReachable onTriggered: { pageStack.push( Qt.resolvedUrl("PluginSettings.qml"), @@ -116,17 +116,17 @@ Kirigami.ScrollablePage { Kirigami.PlaceholderMessage { text: i18nd("kdeconnect-app", "This device is not paired") anchors.centerIn: parent - visible: root.currentDevice && root.currentDevice.isReachable && !root.currentDevice.isTrusted && !root.currentDevice.hasPairingRequests + visible: root.currentDevice && root.currentDevice.isReachable && !root.currentDevice.isPaired && !root.currentDevice.isPairRequestedByPeer helpfulAction: Kirigami.Action { text: i18nd("kdeconnect-app", "Pair") icon.name:"network-connect" - onTriggered: root.currentDevice.requestPair() + onTriggered: root.currentDevice.requestPairing() } } Kirigami.PlaceholderMessage { text: i18n("Pair requested") - visible: root.currentDevice && root.currentDevice.hasPairingRequests + visible: root.currentDevice && root.currentDevice.isPairRequestedByPeer anchors.centerIn: parent spacing: Kirigami.Units.largeSpacing RowLayout { @@ -139,7 +139,7 @@ Kirigami.ScrollablePage { QQC2.Button { text: i18nd("kdeconnect-app", "Reject") icon.name:"dialog-cancel" - onClicked: root.currentDevice.rejectPairing() + onClicked: root.currentDevice.cancelPairing() } } } diff --git a/cli/kdeconnect-cli.cpp b/cli/kdeconnect-cli.cpp index d1bdc62a8..180752a34 100644 --- a/cli/kdeconnect-cli.cpp +++ b/cli/kdeconnect-cli.cpp @@ -93,7 +93,6 @@ int main(int argc, char **argv) if (parser.isSet(QStringLiteral("a"))) { available = true; } else { - blockOnReply(iface.acquireDiscoveryMode(id)); QThread::sleep(2); } const QStringList devices = blockOnReply(iface.devices(available, available)); @@ -115,12 +114,12 @@ int main(int argc, char **argv) DeviceDbusInterface deviceIface(id); QString statusInfo; const bool isReachable = deviceIface.isReachable(); - const bool isTrusted = deviceIface.isTrusted(); - if (isReachable && isTrusted) { + const bool isPaired = deviceIface.isPaired(); + if (isReachable && isPaired) { statusInfo = i18n("(paired and reachable)"); } else if (isReachable) { statusInfo = i18n("(reachable)"); - } else if (isTrusted) { + } else if (isPaired) { statusInfo = i18n("(paired)"); } QTextStream(stdout) << "- " << deviceIface.name() << ": " << deviceIface.id() << ' ' << statusInfo << Qt::endl; @@ -132,15 +131,14 @@ int main(int argc, char **argv) QTextStream(stderr) << i18n("No devices found") << Qt::endl; } - blockOnReply(iface.releaseDiscoveryMode(id)); } else if (parser.isSet(QStringLiteral("shell-device-autocompletion"))) { // Outputs a list of reachable devices in zsh autocomplete format, with the name as description const QStringList devices = blockOnReply(iface.devices(true, false)); for (const QString &id : devices) { DeviceDbusInterface deviceIface(id); QString statusInfo; - const bool isTrusted = deviceIface.isTrusted(); - if (isTrusted) { + const bool isPaired = deviceIface.isPaired(); + if (isPaired) { statusInfo = i18n("(paired)"); } else { statusInfo = i18n("(unpaired)"); @@ -239,7 +237,6 @@ int main(int argc, char **argv) // Device doesn't exist, go into discovery mode and wait up to 30 seconds for the device to appear QEventLoop wait; QTextStream(stderr) << i18n("waiting for device...") << Qt::endl; - blockOnReply(iface.acquireDiscoveryMode(id)); QObject::connect(&iface, &DaemonDbusInterface::deviceAdded, &iface, [&](const QString &deviceAddedId) { if (device == deviceAddedId) { @@ -253,16 +250,15 @@ int main(int argc, char **argv) if (!dev.isReachable()) { QTextStream(stderr) << i18n("Device not found") << Qt::endl; - } else if (blockOnReply(dev.isTrusted())) { + } else if (blockOnReply(dev.isPaired())) { QTextStream(stderr) << i18n("Already paired") << Qt::endl; } else { QTextStream(stderr) << i18n("Pair requested") << Qt::endl; - blockOnReply(dev.requestPair()); + blockOnReply(dev.requestPairing()); } - blockOnReply(iface.releaseDiscoveryMode(id)); } else if (parser.isSet(QStringLiteral("unpair"))) { DeviceDbusInterface dev(device); - if (!dev.isTrusted()) { + if (!dev.isPaired()) { QTextStream(stderr) << i18n("Already not paired") << Qt::endl; } else { QTextStream(stderr) << i18n("Unpaired") << Qt::endl; diff --git a/core/backends/bluetooth/CMakeLists.txt b/core/backends/bluetooth/CMakeLists.txt index 9f4b7ca1e..9e8d46c0d 100644 --- a/core/backends/bluetooth/CMakeLists.txt +++ b/core/backends/bluetooth/CMakeLists.txt @@ -7,7 +7,6 @@ set(backends_kdeconnect_SRCS backends/bluetooth/connectionmultiplexer.cpp backends/bluetooth/bluetoothlinkprovider.cpp backends/bluetooth/bluetoothdevicelink.cpp - backends/bluetooth/bluetoothpairinghandler.cpp backends/bluetooth/bluetoothdownloadjob.cpp backends/bluetooth/bluetoothuploadjob.cpp diff --git a/core/backends/bluetooth/bluetoothdevicelink.cpp b/core/backends/bluetooth/bluetoothdevicelink.cpp index facf5deed..e4891e5b6 100644 --- a/core/backends/bluetooth/bluetoothdevicelink.cpp +++ b/core/backends/bluetooth/bluetoothdevicelink.cpp @@ -22,7 +22,6 @@ BluetoothDeviceLink::BluetoothDeviceLink(const QString &deviceId, , mSocketReader(new DeviceLineReader(socket.data(), this)) , mConnection(connection) , mChannel(socket) - , mPairingHandler(new BluetoothPairingHandler(this)) { connect(mSocketReader, &DeviceLineReader::readyRead, this, &BluetoothDeviceLink::dataReceived); @@ -51,21 +50,6 @@ bool BluetoothDeviceLink::sendPacket(NetworkPacket &np) return (written != -1); } -void BluetoothDeviceLink::userRequestsPair() -{ - mPairingHandler->requestPairing(); -} - -void BluetoothDeviceLink::userRequestsUnpair() -{ - mPairingHandler->unpair(); -} - -bool BluetoothDeviceLink::linkShouldBeKeptAlive() -{ - return pairStatus() == Paired; -} - void BluetoothDeviceLink::dataReceived() { if (mSocketReader->bytesAvailable() == 0) @@ -78,12 +62,6 @@ void BluetoothDeviceLink::dataReceived() NetworkPacket packet((QString())); NetworkPacket::unserialize(serializedPacket, &packet); - if (packet.type() == PACKET_TYPE_PAIR) { - // TODO: Handle pair/unpair requests and forward them (to the pairing handler?) - mPairingHandler->packetReceived(packet); - return; - } - if (packet.hasPayloadTransferInfo()) { BluetoothDownloadJob *downloadJob = new BluetoothDownloadJob(mConnection, packet.payloadTransferInfo(), this); downloadJob->start(); diff --git a/core/backends/bluetooth/bluetoothdevicelink.h b/core/backends/bluetooth/bluetoothdevicelink.h index 8c70bb499..f5e5f21c9 100644 --- a/core/backends/bluetooth/bluetoothdevicelink.h +++ b/core/backends/bluetooth/bluetoothdevicelink.h @@ -14,7 +14,6 @@ #include "../devicelinereader.h" #include "../devicelink.h" -#include "bluetoothpairinghandler.h" class ConnectionMultiplexer; class MultiplexChannel; @@ -29,10 +28,6 @@ public: virtual QString name() override; bool sendPacket(NetworkPacket &np) override; - virtual void userRequestsPair() override; - virtual void userRequestsUnpair() override; - - virtual bool linkShouldBeKeptAlive() override; QSslCertificate certificate() const override; private Q_SLOTS: @@ -42,7 +37,6 @@ private: DeviceLineReader *mSocketReader; ConnectionMultiplexer *mConnection; QSharedPointer mChannel; - BluetoothPairingHandler *mPairingHandler; void sendMessage(const QString mMessage); }; diff --git a/core/backends/bluetooth/bluetoothpairinghandler.cpp b/core/backends/bluetooth/bluetoothpairinghandler.cpp deleted file mode 100644 index f544e6f2f..000000000 --- a/core/backends/bluetooth/bluetoothpairinghandler.cpp +++ /dev/null @@ -1,137 +0,0 @@ -/** - * SPDX-FileCopyrightText: 2015 Vineet Garg - * - * SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL - */ - -#include "bluetoothpairinghandler.h" - -#include - -#include "core_debug.h" -#include "daemon.h" -#include "kdeconnectconfig.h" -#include "networkpackettypes.h" - -BluetoothPairingHandler::BluetoothPairingHandler(DeviceLink *deviceLink) - : PairingHandler(deviceLink) - , m_status(NotPaired) -{ - m_pairingTimeout.setSingleShot(true); - m_pairingTimeout.setInterval(pairingTimeoutMsec()); - connect(&m_pairingTimeout, &QTimer::timeout, this, &BluetoothPairingHandler::pairingTimeout); -} - -void BluetoothPairingHandler::packetReceived(const NetworkPacket &np) -{ - qCDebug(KDECONNECT_CORE) << "Pairing packet received!" << np.serialize(); - - m_pairingTimeout.stop(); - - bool wantsPair = np.get(QStringLiteral("pair")); - - if (wantsPair) { - if (isPairRequested()) { // We started pairing - - qCDebug(KDECONNECT_CORE) << "Pair answer"; - setInternalPairStatus(Paired); - - } else { - qCDebug(KDECONNECT_CORE) << "Pair request"; - - if (isPaired()) { // I'm already paired, but they think I'm not - acceptPairing(); - return; - } - - setInternalPairStatus(RequestedByPeer); - } - - } else { // wantsPair == false - - qCDebug(KDECONNECT_CORE) << "Unpair request"; - - setInternalPairStatus(NotPaired); - if (isPairRequested()) { - Q_EMIT pairingError(i18n("Canceled by other peer")); - } - } -} - -bool BluetoothPairingHandler::requestPairing() -{ - switch (m_status) { - case Paired: - Q_EMIT pairingError(i18n("%1: Already paired", deviceLink()->name())); - return false; - case Requested: - Q_EMIT pairingError(i18n("%1: Pairing already requested for this device", deviceLink()->name())); - return false; - case RequestedByPeer: - qCDebug(KDECONNECT_CORE) << deviceLink()->name() << " : Pairing already started by the other end, accepting their request."; - acceptPairing(); - return false; - case NotPaired:; - } - - NetworkPacket np(PACKET_TYPE_PAIR); - np.set(QStringLiteral("pair"), true); - bool success; - success = deviceLink()->sendPacket(np); - if (success) { - setInternalPairStatus(Requested); - m_pairingTimeout.start(); - } - return success; -} - -bool BluetoothPairingHandler::acceptPairing() -{ - qCDebug(KDECONNECT_CORE) << "User accepts pairing"; - m_pairingTimeout.stop(); // Just in case it is started - NetworkPacket np(PACKET_TYPE_PAIR); - np.set(QStringLiteral("pair"), true); - bool success = deviceLink()->sendPacket(np); - if (success) { - setInternalPairStatus(Paired); - } - return success; -} - -void BluetoothPairingHandler::rejectPairing() -{ - qCDebug(KDECONNECT_CORE) << "User rejects pairing"; - NetworkPacket np(PACKET_TYPE_PAIR); - np.set(QStringLiteral("pair"), false); - deviceLink()->sendPacket(np); - setInternalPairStatus(NotPaired); -} - -void BluetoothPairingHandler::unpair() -{ - NetworkPacket np(PACKET_TYPE_PAIR); - np.set(QStringLiteral("pair"), false); - deviceLink()->sendPacket(np); - setInternalPairStatus(NotPaired); -} - -void BluetoothPairingHandler::pairingTimeout() -{ - NetworkPacket np(PACKET_TYPE_PAIR); - np.set(QStringLiteral("pair"), false); - deviceLink()->sendPacket(np); - setInternalPairStatus(NotPaired); // Will emit the change as well - Q_EMIT pairingError(i18n("Timed out")); -} - -void BluetoothPairingHandler::setInternalPairStatus(BluetoothPairingHandler::InternalPairStatus status) -{ - m_status = status; - if (status == Paired) { - deviceLink()->setPairStatus(DeviceLink::Paired); - } else if (status == NotPaired) { - deviceLink()->setPairStatus(DeviceLink::NotPaired); - } else if (status == RequestedByPeer) { - Q_EMIT deviceLink()->pairingRequest(this); - } -} diff --git a/core/backends/bluetooth/bluetoothpairinghandler.h b/core/backends/bluetooth/bluetoothpairinghandler.h deleted file mode 100644 index 374cdae00..000000000 --- a/core/backends/bluetooth/bluetoothpairinghandler.h +++ /dev/null @@ -1,58 +0,0 @@ -/** - * SPDX-FileCopyrightText: 2015 Vineet Garg - * - * SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL - */ - -#ifndef KDECONNECT_BLUETOOTHPAIRINGHANDLER_H -#define KDECONNECT_BLUETOOTHPAIRINGHANDLER_H - -#include "../devicelink.h" -#include "../pairinghandler.h" -#include "device.h" - -#include - -// This class is used pairing related stuff. It has direct access to links and can directly send packets -class BluetoothPairingHandler : public PairingHandler -{ -public: - enum InternalPairStatus { - NotPaired, - Requested, - RequestedByPeer, - Paired, - }; - - BluetoothPairingHandler(DeviceLink *deviceLink); - virtual ~BluetoothPairingHandler() - { - } - - void packetReceived(const NetworkPacket &np) override; - bool requestPairing() override; - bool acceptPairing() override; - void rejectPairing() override; - void unpair() override; - - bool isPairRequested() const - { - return m_status == Requested; - } - bool isPaired() const - { - return m_status == Paired; - } - -private Q_SLOTS: - void pairingTimeout(); - -protected: - void setInternalPairStatus(InternalPairStatus status); - - QTimer m_pairingTimeout; - - InternalPairStatus m_status; -}; - -#endif // KDECONNECT_BLUETOOTHPAIRINGHANDLER_H diff --git a/core/backends/devicelink.cpp b/core/backends/devicelink.cpp index 8ef9987af..7a29a1c0e 100644 --- a/core/backends/devicelink.cpp +++ b/core/backends/devicelink.cpp @@ -12,17 +12,9 @@ DeviceLink::DeviceLink(const QString &deviceId, LinkProvider *parent) : QObject(parent) , m_deviceId(deviceId) , m_linkProvider(parent) - , m_pairStatus(NotPaired) { Q_ASSERT(!deviceId.isEmpty()); setProperty("deviceId", deviceId); } -void DeviceLink::setPairStatus(DeviceLink::PairStatus status) -{ - if (m_pairStatus != status) { - m_pairStatus = status; - Q_EMIT pairStatusChanged(status); - } -} diff --git a/core/backends/devicelink.h b/core/backends/devicelink.h index b38074deb..932976149 100644 --- a/core/backends/devicelink.h +++ b/core/backends/devicelink.h @@ -22,7 +22,6 @@ class DeviceLink : public QObject Q_OBJECT public: - enum PairStatus { NotPaired, Paired }; DeviceLink(const QString &deviceId, LinkProvider *parent); ~DeviceLink() override = default; @@ -40,35 +39,14 @@ public: virtual bool sendPacket(NetworkPacket &np) = 0; - // user actions - virtual void userRequestsPair() = 0; - virtual void userRequestsUnpair() = 0; - - PairStatus pairStatus() const - { - return m_pairStatus; - } - virtual void setPairStatus(PairStatus status); - - // The daemon will periodically destroy unpaired links if this returns false - virtual bool linkShouldBeKeptAlive() - { - return false; - } - virtual QSslCertificate certificate() const = 0; Q_SIGNALS: - void pairingRequest(PairingHandler *handler); - void pairingRequestExpired(PairingHandler *handler); - void pairStatusChanged(DeviceLink::PairStatus status); - void pairingError(const QString &error); void receivedPacket(const NetworkPacket &np); private: const QString m_deviceId; LinkProvider *m_linkProvider; - PairStatus m_pairStatus; }; #endif diff --git a/core/backends/lan/CMakeLists.txt b/core/backends/lan/CMakeLists.txt index 6a838efbe..b8be9684b 100644 --- a/core/backends/lan/CMakeLists.txt +++ b/core/backends/lan/CMakeLists.txt @@ -5,7 +5,6 @@ set(backends_kdeconnect_SRCS backends/lan/server.cpp backends/lan/lanlinkprovider.cpp backends/lan/landevicelink.cpp - backends/lan/lanpairinghandler.cpp backends/lan/compositeuploadjob.cpp backends/lan/uploadjob.cpp backends/lan/socketlinereader.cpp diff --git a/core/backends/lan/landevicelink.cpp b/core/backends/lan/landevicelink.cpp index a17889634..182f218d4 100644 --- a/core/backends/lan/landevicelink.cpp +++ b/core/backends/lan/landevicelink.cpp @@ -43,7 +43,6 @@ void LanDeviceLink::reset(QSslSocket *socket, ConnectionStarted connectionSource m_connectionSource = connectionSource; QString certString = KdeConnectConfig::instance().getDeviceProperty(deviceId(), QStringLiteral("certificate")); - DeviceLink::setPairStatus(certString.isEmpty() ? PairStatus::NotPaired : PairStatus::Paired); } QHostAddress LanDeviceLink::hostAddress() const @@ -109,12 +108,6 @@ void LanDeviceLink::dataReceived() // qCDebug(KDECONNECT_CORE) << "LanDeviceLink dataReceived" << serializedPacket; - if (packet.type() == PACKET_TYPE_PAIR) { - // TODO: Handle pair/unpair requests and forward them (to the pairing handler?) - qobject_cast(provider())->incomingPairPacket(this, packet); - return; - } - if (packet.hasPayloadTransferInfo()) { // qCDebug(KDECONNECT_CORE) << "HasPayloadTransferInfo"; const QVariantMap transferInfo = packet.payloadTransferInfo(); @@ -140,43 +133,6 @@ void LanDeviceLink::dataReceived() } } -void LanDeviceLink::userRequestsPair() -{ - if (m_socketLineReader->peerCertificate().isNull()) { - Q_EMIT pairingError(i18n("This device cannot be paired because it is running an old version of KDE Connect.")); - } else { - qobject_cast(provider())->userRequestsPair(deviceId()); - } -} - -void LanDeviceLink::userRequestsUnpair() -{ - qobject_cast(provider())->userRequestsUnpair(deviceId()); -} - -void LanDeviceLink::setPairStatus(PairStatus status) -{ - if (status == Paired && m_socketLineReader->peerCertificate().isNull()) { - Q_EMIT pairingError(i18n("This device cannot be paired because it is running an old version of KDE Connect.")); - return; - } - - DeviceLink::setPairStatus(status); - if (status == Paired) { - Q_ASSERT(KdeConnectConfig::instance().trustedDevices().contains(deviceId())); - KdeConnectConfig::instance().setDeviceProperty(deviceId(), QStringLiteral("certificate"), QString::fromLatin1(certificate().toPem())); - } -} - -bool LanDeviceLink::linkShouldBeKeptAlive() -{ - return true; // FIXME: Current implementation is broken, so for now we will keep links always established - - // We keep the remotely initiated connections, since the remotes require them if they want to request - // pairing to us, or connections that are already paired. TODO: Keep connections in the process of pairing - // return (mConnectionSource == ConnectionStarted::Remotely || pairStatus() == Paired); -} - QSslCertificate LanDeviceLink::certificate() const { return m_socketLineReader->peerCertificate(); diff --git a/core/backends/lan/landevicelink.h b/core/backends/lan/landevicelink.h index 342515f93..bbe9428b8 100644 --- a/core/backends/lan/landevicelink.h +++ b/core/backends/lan/landevicelink.h @@ -33,13 +33,6 @@ public: QString name() override; bool sendPacket(NetworkPacket &np) override; - void userRequestsPair() override; - void userRequestsUnpair() override; - - void setPairStatus(PairStatus status) override; - - bool linkShouldBeKeptAlive() override; - QHostAddress hostAddress() const; QSslCertificate certificate() const override; diff --git a/core/backends/lan/lanlinkprovider.cpp b/core/backends/lan/lanlinkprovider.cpp index 70e683934..724c54642 100644 --- a/core/backends/lan/lanlinkprovider.cpp +++ b/core/backends/lan/lanlinkprovider.cpp @@ -32,7 +32,6 @@ #include "daemon.h" #include "kdeconnectconfig.h" #include "landevicelink.h" -#include "lanpairinghandler.h" #include "qtcompat_p.h" #define MIN_VERSION_WITH_SSL_SUPPORT 6 @@ -537,10 +536,6 @@ void LanLinkProvider::deviceLinkDestroyed(QObject *destroyedDeviceLink) if (linkIterator != m_links.end()) { Q_ASSERT(linkIterator.value() == destroyedDeviceLink); m_links.erase(linkIterator); - auto pairingHandler = m_pairingHandlers.take(id); - if (pairingHandler) { - pairingHandler->deleteLater(); - } } } @@ -648,42 +643,6 @@ void LanLinkProvider::addLink(const QString &deviceId, QSslSocket *socket, Netwo } connect(deviceLink, &QObject::destroyed, this, &LanLinkProvider::deviceLinkDestroyed); m_links[deviceId] = deviceLink; - if (m_pairingHandlers.contains(deviceId)) { - // We shouldn't have a pairinghandler if we didn't have a link. - // Crash if debug, recover if release (by setting the new devicelink to the old pairinghandler) - Q_ASSERT(m_pairingHandlers.contains(deviceId)); - m_pairingHandlers[deviceId]->setDeviceLink(deviceLink); - } } Q_EMIT onConnectionReceived(*receivedPacket, deviceLink); } - -LanPairingHandler *LanLinkProvider::createPairingHandler(DeviceLink *link) -{ - LanPairingHandler *ph = m_pairingHandlers.value(link->deviceId()); - if (!ph) { - ph = new LanPairingHandler(link); - qCDebug(KDECONNECT_CORE) << "creating pairing handler for" << link->deviceId(); - connect(ph, &LanPairingHandler::pairingError, link, &DeviceLink::pairingError); - m_pairingHandlers[link->deviceId()] = ph; - } - return ph; -} - -void LanLinkProvider::userRequestsPair(const QString &deviceId) -{ - LanPairingHandler *ph = createPairingHandler(m_links.value(deviceId)); - ph->requestPairing(); -} - -void LanLinkProvider::userRequestsUnpair(const QString &deviceId) -{ - LanPairingHandler *ph = createPairingHandler(m_links.value(deviceId)); - ph->unpair(); -} - -void LanLinkProvider::incomingPairPacket(DeviceLink *deviceLink, const NetworkPacket &np) -{ - LanPairingHandler *ph = createPairingHandler(deviceLink); - ph->packetReceived(np); -} diff --git a/core/backends/lan/lanlinkprovider.h b/core/backends/lan/lanlinkprovider.h index 034b1f630..4ac0bb5d6 100644 --- a/core/backends/lan/lanlinkprovider.h +++ b/core/backends/lan/lanlinkprovider.h @@ -19,7 +19,6 @@ #include "landevicelink.h" #include "server.h" -class LanPairingHandler; class KDECONNECTCORE_EXPORT LanLinkProvider : public LinkProvider { Q_OBJECT @@ -42,10 +41,6 @@ public: return PRIORITY_HIGH; } - void userRequestsPair(const QString &deviceId); - void userRequestsUnpair(const QString &deviceId); - void incomingPairPacket(DeviceLink *device, const NetworkPacket &np); - static void configureSslSocket(QSslSocket *socket, const QString &deviceId, bool isDeviceTrusted); static void configureSocket(QSslSocket *socket); @@ -73,8 +68,6 @@ private Q_SLOTS: void broadcastToNetwork(); private: - LanPairingHandler *createPairingHandler(DeviceLink *link); - void onNetworkConfigurationChanged(const QNetworkConfiguration &config); void addLink(const QString &deviceId, QSslSocket *socket, NetworkPacket *receivedPacket, LanDeviceLink::ConnectionStarted connectionOrigin); QList getBroadcastAddresses(); @@ -88,7 +81,6 @@ private: quint16 m_udpListenPort; QMap m_links; - QMap m_pairingHandlers; struct PendingConnect { NetworkPacket *np; diff --git a/core/backends/lan/lanpairinghandler.cpp b/core/backends/lan/lanpairinghandler.cpp deleted file mode 100644 index c54344056..000000000 --- a/core/backends/lan/lanpairinghandler.cpp +++ /dev/null @@ -1,129 +0,0 @@ -/** - * SPDX-FileCopyrightText: 2015 Vineet Garg - * - * SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL - */ - -#include "lanpairinghandler.h" - -#include - -#include "core_debug.h" -#include "daemon.h" -#include "kdeconnectconfig.h" -#include "landevicelink.h" -#include "networkpackettypes.h" - -LanPairingHandler::LanPairingHandler(DeviceLink *deviceLink) - : PairingHandler(deviceLink) - , m_status(NotPaired) -{ - m_pairingTimeout.setSingleShot(true); - m_pairingTimeout.setInterval(pairingTimeoutMsec()); - connect(&m_pairingTimeout, &QTimer::timeout, this, &LanPairingHandler::pairingTimeout); -} - -void LanPairingHandler::packetReceived(const NetworkPacket &np) -{ - bool wantsPair = np.get(QStringLiteral("pair")); - - if (wantsPair) { - if (isPairRequested()) { // We started pairing - - qCDebug(KDECONNECT_CORE) << "Pair answer"; - setInternalPairStatus(Paired); - - } else { - qCDebug(KDECONNECT_CORE) << "Pair request"; - - if (isPaired()) { // I'm already paired, but they think I'm not - acceptPairing(); - return; - } - - setInternalPairStatus(RequestedByPeer); - } - - } else { // wantsPair == false - - qCDebug(KDECONNECT_CORE) << "Unpair request"; - - if (isPairRequested()) { - Q_EMIT pairingError(i18n("Canceled by other peer")); - } - setInternalPairStatus(NotPaired); - } -} - -bool LanPairingHandler::requestPairing() -{ - if (m_status == Paired) { - Q_EMIT pairingError(i18n("%1: Already paired", deviceLink()->name())); - return false; - } - if (m_status == RequestedByPeer) { - qCDebug(KDECONNECT_CORE) << deviceLink()->name() << ": Pairing already started by the other end, accepting their request."; - return acceptPairing(); - } - - NetworkPacket np(PACKET_TYPE_PAIR, {{QStringLiteral("pair"), true}}); - const bool success = deviceLink()->sendPacket(np); - if (success) { - setInternalPairStatus(Requested); - } - return success; -} - -bool LanPairingHandler::acceptPairing() -{ - NetworkPacket np(PACKET_TYPE_PAIR, {{QStringLiteral("pair"), true}}); - bool success = deviceLink()->sendPacket(np); - if (success) { - setInternalPairStatus(Paired); - } - return success; -} - -void LanPairingHandler::rejectPairing() -{ - NetworkPacket np(PACKET_TYPE_PAIR, {{QStringLiteral("pair"), false}}); - deviceLink()->sendPacket(np); - setInternalPairStatus(NotPaired); -} - -void LanPairingHandler::unpair() -{ - NetworkPacket np(PACKET_TYPE_PAIR, {{QStringLiteral("pair"), false}}); - deviceLink()->sendPacket(np); - setInternalPairStatus(NotPaired); -} - -void LanPairingHandler::pairingTimeout() -{ - NetworkPacket np(PACKET_TYPE_PAIR, {{QStringLiteral("pair"), false}}); - deviceLink()->sendPacket(np); - setInternalPairStatus(NotPaired); // Will emit the change as well - Q_EMIT pairingError(i18n("Timed out")); -} - -void LanPairingHandler::setInternalPairStatus(LanPairingHandler::InternalPairStatus status) -{ - if (status == Requested || status == RequestedByPeer) { - m_pairingTimeout.start(); - } else { - m_pairingTimeout.stop(); - } - - if (m_status == RequestedByPeer && (status == NotPaired || status == Paired)) { - Q_EMIT deviceLink()->pairingRequestExpired(this); - } else if (status == RequestedByPeer) { - Q_EMIT deviceLink()->pairingRequest(this); - } - - 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 deleted file mode 100644 index 5ad958ee3..000000000 --- a/core/backends/lan/lanpairinghandler.h +++ /dev/null @@ -1,61 +0,0 @@ -/** - * SPDX-FileCopyrightText: 2015 Vineet Garg - * - * SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL - */ - -#ifndef KDECONNECT_LANPAIRINGHANDLER_H -#define KDECONNECT_LANPAIRINGHANDLER_H - -#include -#include - -#include "backends/devicelink.h" -#include "backends/pairinghandler.h" -#include "device.h" - -// This class is used pairing related stuff. It has direct access to links and can directly send packets -class LanPairingHandler : public PairingHandler -{ - Q_OBJECT - -public: - enum InternalPairStatus { - NotPaired, - Requested, - RequestedByPeer, - Paired, - }; - - LanPairingHandler(DeviceLink *deviceLink); - ~LanPairingHandler() override - { - } - - void packetReceived(const NetworkPacket &np) override; - bool requestPairing() override; - bool acceptPairing() override; - void rejectPairing() override; - void unpair() override; - - bool isPairRequested() const - { - return m_status == Requested; - } - bool isPaired() const - { - return m_status == Paired; - } - -private Q_SLOTS: - void pairingTimeout(); - -protected: - void setInternalPairStatus(InternalPairStatus status); - - QTimer m_pairingTimeout; - - InternalPairStatus m_status; -}; - -#endif // KDECONNECT_LANPAIRINGHANDLER_H diff --git a/core/backends/loopback/loopbackdevicelink.h b/core/backends/loopback/loopbackdevicelink.h index f833793da..628ab7706 100644 --- a/core/backends/loopback/loopbackdevicelink.h +++ b/core/backends/loopback/loopbackdevicelink.h @@ -21,15 +21,6 @@ public: QString name() override; bool sendPacket(NetworkPacket &np) override; - void userRequestsPair() override - { - setPairStatus(Paired); - } - void userRequestsUnpair() override - { - setPairStatus(NotPaired); - } - QSslCertificate certificate() const override { return QSslCertificate(); diff --git a/core/backends/pairinghandler.cpp b/core/backends/pairinghandler.cpp index 2780831b9..a77e9b5ad 100644 --- a/core/backends/pairinghandler.cpp +++ b/core/backends/pairinghandler.cpp @@ -6,19 +6,138 @@ #include "pairinghandler.h" -PairingHandler::PairingHandler(DeviceLink *parent) +#include "core_debug.h" + +#include + +PairingHandler::PairingHandler(Device *parent, PairState initialState) : QObject(parent) - , m_deviceLink(parent) + , m_device(parent) + , m_pairState(initialState) { + m_pairingTimeout.setSingleShot(true); + m_pairingTimeout.setInterval(pairingTimeoutMsec); + connect(&m_pairingTimeout, &QTimer::timeout, this, &PairingHandler::pairingTimeout); } -void PairingHandler::setDeviceLink(DeviceLink *dl) +void PairingHandler::packetReceived(const NetworkPacket &np) { - setParent(dl); - m_deviceLink = dl; + m_pairingTimeout.stop(); + bool wantsPair = np.get(QStringLiteral("pair")); + if (wantsPair) { + switch (m_pairState) { + case PairState::Requested: + pairingDone(); + break; + case PairState::RequestedByPeer: + qCDebug(KDECONNECT_CORE) << "Ignoring second pairing request before the first one timed out"; + break; + case PairState::Paired: + qCDebug(KDECONNECT_CORE) << "Auto-accepting pairing request from a device we already trusted"; + acceptPairing(); + break; + case PairState::NotPaired: + m_pairState = PairState::RequestedByPeer; + m_pairingTimeout.start(); + Q_EMIT incomingPairRequest(); + break; + } + } else { // wantsPair == false + qCDebug(KDECONNECT_CORE) << "Unpair request received"; + switch (m_pairState) { + case PairState::NotPaired: + qCDebug(KDECONNECT_CORE) << "Ignoring unpair request for already unpaired device"; + break; + case PairState::Requested: // We started pairing and got rejected + case PairState::RequestedByPeer: // They stared pairing, then cancelled + m_pairState = PairState::NotPaired; + Q_EMIT pairingFailed(i18n("Canceled by other peer")); + break; + case PairState::Paired: + m_pairState = PairState::NotPaired; + Q_EMIT unpaired(); + break; + } + } } -DeviceLink *PairingHandler::deviceLink() const +bool PairingHandler::requestPairing() { - return m_deviceLink; + m_pairingTimeout.stop(); + + if (m_pairState == PairState::Paired) { + qWarning() << m_device->name() << ": requestPairing was called on an already paired device."; + Q_EMIT pairingFailed(i18n("%1: Already paired", m_device->name())); + return false; + } + if (m_pairState == PairState::RequestedByPeer) { + qWarning() << m_device->name() << ": Pairing already started by the other end, accepting their request."; + return acceptPairing(); + } + + if (!m_device->isReachable()) { + Q_EMIT pairingFailed(i18n("%1: Device not reachable", m_device->name())); + return false; + } + + m_pairingTimeout.stop(); + + m_pairState = PairState::Requested; + + NetworkPacket np(PACKET_TYPE_PAIR, {{QStringLiteral("pair"), true}}); + const bool success = m_device->sendPacket(np); + if (success) { + m_pairingTimeout.start(); + } else { + qWarning() << m_device->name() << ": Failed to send pair request packet."; + m_pairState = PairState::NotPaired; + Q_EMIT pairingFailed(i18n("%1: Device not reachable", m_device->name())); + } + return success; +} + +bool PairingHandler::acceptPairing() +{ + m_pairingTimeout.stop(); + NetworkPacket np(PACKET_TYPE_PAIR, {{QStringLiteral("pair"), true}}); + const bool success = m_device->sendPacket(np); + if (success) { + pairingDone(); + } else { + qWarning() << "Failed to send packet accepting pairing"; + m_pairState = PairState::NotPaired; + Q_EMIT pairingFailed(i18n("Device not reachable")); + } + return success; +} + +void PairingHandler::cancelPairing() +{ + m_pairingTimeout.stop(); + m_pairState = PairState::NotPaired; + NetworkPacket np(PACKET_TYPE_PAIR, {{QStringLiteral("pair"), false}}); + m_device->sendPacket(np); + Q_EMIT pairingFailed(i18n("Cancelled by user")); +} + +void PairingHandler::unpair() +{ + m_pairState = PairState::NotPaired; + NetworkPacket np(PACKET_TYPE_PAIR, {{QStringLiteral("pair"), false}}); + m_device->sendPacket(np); + Q_EMIT unpaired(); +} + +void PairingHandler::pairingTimeout() +{ + NetworkPacket np(PACKET_TYPE_PAIR, {{QStringLiteral("pair"), false}}); + m_device->sendPacket(np); + m_pairState = PairState::NotPaired; + Q_EMIT pairingFailed(i18n("Timed out")); +} + +void PairingHandler::pairingDone() { + qCDebug(KDECONNECT_CORE) << "Pairing done"; + m_pairState = PairState::Paired; + Q_EMIT pairingSuccessful(); } diff --git a/core/backends/pairinghandler.h b/core/backends/pairinghandler.h index 3a70c8e99..bc3773479 100644 --- a/core/backends/pairinghandler.h +++ b/core/backends/pairinghandler.h @@ -7,48 +7,48 @@ #ifndef KDECONNECT_PAIRINGHANDLER_H #define KDECONNECT_PAIRINGHANDLER_H -#include "devicelink.h" +#include "device.h" #include "networkpacket.h" +#include "pairstate.h" -/* - * This class separates the pairing interface for each type of link. - * Since different links can pair via different methods, like for LanLink certificate and public key should be shared, - * for Bluetooth link they should be paired via bluetooth etc. - * Each "Device" instance maintains a hash map for these pairing handlers so that there can be single pairing handler per - * per link type per device. - * Pairing handler keeps information about device, latest link, and pair status of the link - * During first pairing process, the pairing process is nearly same as old process. - * After that if any one of the link is paired, then we can say that device is paired, so new link will pair automatically - */ +#include class KDECONNECTCORE_EXPORT PairingHandler : public QObject { Q_OBJECT - public: - PairingHandler(DeviceLink *parent); + const static int pairingTimeoutMsec = 30 * 1000; // 30 seconds of timeout + + PairingHandler(Device *parent, PairState initialState); ~PairingHandler() override = default; - DeviceLink *deviceLink() const; - void setDeviceLink(DeviceLink *dl); + void packetReceived(const NetworkPacket &np); - virtual void packetReceived(const NetworkPacket &np) = 0; - virtual void unpair() = 0; - static int pairingTimeoutMsec() - { - return 30 * 1000; - } // 30 seconds of timeout (default), subclasses that use different values should override + PairState pairState() { return m_pairState; } public Q_SLOTS: - virtual bool requestPairing() = 0; - virtual bool acceptPairing() = 0; - virtual void rejectPairing() = 0; + bool requestPairing(); + bool acceptPairing(); + void cancelPairing(); + void unpair(); Q_SIGNALS: - void pairingError(const QString &errorMessage); + void incomingPairRequest(); + void pairingFailed(const QString &errorMessage); + void pairingSuccessful(); + void unpaired(); + private: - DeviceLink *m_deviceLink; + void pairingDone(); + + QTimer m_pairingTimeout; + Device *m_device; + PairState m_pairState; + +private Q_SLOTS: + void pairingTimeout(); + }; #endif // KDECONNECT_PAIRINGHANDLER_H diff --git a/core/daemon.cpp b/core/daemon.cpp index 20d2cca8c..e06abae7b 100644 --- a/core/daemon.cpp +++ b/core/daemon.cpp @@ -40,7 +40,6 @@ struct DaemonPrivate { // Every known device QMap m_devices; - QSet m_discoveryModeAcquisitions; bool m_testMode; }; @@ -101,28 +100,6 @@ void Daemon::init() qCDebug(KDECONNECT_CORE) << "Daemon started"; } -void Daemon::acquireDiscoveryMode(const QString &key) -{ - bool oldState = d->m_discoveryModeAcquisitions.isEmpty(); - - d->m_discoveryModeAcquisitions.insert(key); - - if (oldState != d->m_discoveryModeAcquisitions.isEmpty()) { - forceOnNetworkChange(); - } -} - -void Daemon::releaseDiscoveryMode(const QString &key) -{ - bool oldState = d->m_discoveryModeAcquisitions.isEmpty(); - - d->m_discoveryModeAcquisitions.remove(key); - - if (oldState != d->m_discoveryModeAcquisitions.isEmpty()) { - cleanDevices(); - } -} - void Daemon::removeDevice(Device *device) { d->m_devices.remove(device->id()); @@ -131,20 +108,6 @@ void Daemon::removeDevice(Device *device) Q_EMIT deviceListChanged(); } -void Daemon::cleanDevices() -{ - const auto devs = d->m_devices; - for (Device *device : devs) { - if (device->isTrusted()) { - continue; - } - device->cleanUnneededLinks(); - // If there are no links remaining - if (!device->isReachable()) { - removeDevice(device); - } - } -} void Daemon::forceOnNetworkChange() { @@ -175,7 +138,7 @@ QStringList Daemon::devices(bool onlyReachable, bool onlyTrusted) const for (Device *device : qAsConst(d->m_devices)) { if (onlyReachable && !device->isReachable()) continue; - if (onlyTrusted && !device->isTrusted()) + if (onlyTrusted && !device->isPaired()) continue; ret.append(device->id()); } @@ -188,7 +151,7 @@ QMap Daemon::deviceNames(bool onlyReachable, bool onlyTrusted) for (Device *device : qAsConst(d->m_devices)) { if (onlyReachable && !device->isReachable()) continue; - if (onlyTrusted && !device->isTrusted()) + if (onlyTrusted && !device->isPaired()) continue; ret[device->id()] = device->name(); } @@ -213,13 +176,7 @@ void Daemon::onNewDeviceLink(const NetworkPacket &identityPacket, DeviceLink *dl } else { qCDebug(KDECONNECT_CORE) << "It is a new device" << identityPacket.get(QStringLiteral("deviceName")); Device *device = new Device(this, identityPacket, dl); - - // we discard the connections that we created but it's not paired. - if (!isDiscoveringDevices() && !device->isTrusted() && !dl->linkShouldBeKeptAlive()) { - device->deleteLater(); - } else { - addDevice(device); - } + addDevice(device); } } @@ -229,7 +186,7 @@ void Daemon::onDeviceStatusChanged() // qCDebug(KDECONNECT_CORE) << "Device" << device->name() << "status changed. Reachable:" << device->isReachable() << ". Paired: " << device->isPaired(); - if (!device->isReachable() && !device->isTrusted()) { + if (!device->isReachable() && !device->isPaired()) { // qCDebug(KDECONNECT_CORE) << "Destroying device" << device->name(); removeDevice(device); } else { @@ -284,15 +241,10 @@ QList Daemon::devicesList() const return d->m_devices.values(); } -bool Daemon::isDiscoveringDevices() const -{ - return !d->m_discoveryModeAcquisitions.isEmpty(); -} - QString Daemon::deviceIdByName(const QString &name) const { for (Device *device : qAsConst(d->m_devices)) { - if (device->name() == name && device->isTrusted()) + if (device->name() == name && device->isPaired()) return device->id(); } return {}; @@ -302,10 +254,11 @@ void Daemon::addDevice(Device *device) { const QString id = device->id(); connect(device, &Device::reachableChanged, this, &Daemon::onDeviceStatusChanged); - connect(device, &Device::trustedChanged, this, &Daemon::onDeviceStatusChanged); - connect(device, &Device::hasPairingRequestsChanged, this, &Daemon::pairingRequestsChanged); - connect(device, &Device::hasPairingRequestsChanged, this, [this, device](bool hasPairingRequests) { - if (hasPairingRequests) + connect(device, &Device::pairStateChanged, this, &Daemon::onDeviceStatusChanged); + connect(device, &Device::pairStateChanged, this, &Daemon::pairingRequestsChanged); + connect(device, &Device::pairStateChanged, this, [this, device](int pairStateAsInt) { + PairState pairState = (PairState)pairStateAsInt; + if (pairState == PairState::RequestedByPeer) askPairingConfirmation(device); }); d->m_devices[id] = device; @@ -318,7 +271,7 @@ QStringList Daemon::pairingRequests() const { QStringList ret; for (Device *dev : qAsConst(d->m_devices)) { - if (dev->hasPairingRequests()) + if (dev->isPairRequestedByPeer()) ret += dev->id(); } return ret; diff --git a/core/daemon.h b/core/daemon.h index f33caa017..f0d5e3af4 100644 --- a/core/daemon.h +++ b/core/daemon.h @@ -24,7 +24,6 @@ class KDECONNECTCORE_EXPORT Daemon : public QObject { Q_OBJECT Q_CLASSINFO("D-Bus Interface", "org.kde.kdeconnect.daemon") - Q_PROPERTY(bool isDiscoveringDevices READ isDiscoveringDevices) Q_PROPERTY(QStringList pairingRequests READ pairingRequests NOTIFY pairingRequestsChanged) Q_PROPERTY(QStringList customDevices READ customDevices WRITE setCustomDevices NOTIFY customDevicesChanged) @@ -54,9 +53,6 @@ public: Q_SCRIPTABLE QString selfId() const; public Q_SLOTS: - Q_SCRIPTABLE void acquireDiscoveryMode(const QString &id); - Q_SCRIPTABLE void releaseDiscoveryMode(const QString &id); - Q_SCRIPTABLE void forceOnNetworkChange(); /// don't try to turn into Q_PROPERTY, it doesn't work @@ -90,9 +86,7 @@ private: protected: void addDevice(Device *device); - bool isDiscoveringDevices() const; void removeDevice(Device *d); - void cleanDevices(); QScopedPointer d; }; diff --git a/core/device.cpp b/core/device.cpp index 6544233cb..619734c78 100644 --- a/core/device.cpp +++ b/core/device.cpp @@ -39,6 +39,7 @@ public: ~DevicePrivate() { + delete m_pairingHandler; qDeleteAll(m_deviceLinks); m_deviceLinks.clear(); } @@ -54,7 +55,7 @@ public: QMultiMap m_pluginsByIncomingCapability; QSet m_supportedPlugins; QSet m_allPlugins; - QSet m_pairRequests; + PairingHandler* m_pairingHandler; }; static void warn(const QString &info) @@ -66,6 +67,8 @@ Device::Device(QObject *parent, const QString &id) : QObject(parent) , d(new Device::DevicePrivate(id)) { + d->m_pairingHandler = new PairingHandler(this, PairState::Paired); + d->m_protocolVersion = NetworkPacket::s_protocolVersion; KdeConnectConfig::DeviceInfo info = KdeConnectConfig::instance().getTrustedDevice(d->m_deviceId); @@ -79,13 +82,17 @@ Device::Device(QObject *parent, const QString &id) d->m_allPlugins = PluginLoader::instance()->getPluginList().toSet(); d->m_supportedPlugins = d->m_allPlugins; - connect(this, &Device::pairingError, this, &warn); + connect(d->m_pairingHandler, &PairingHandler::incomingPairRequest, this, &Device::pairingHandler_incomingPairRequest); + connect(d->m_pairingHandler, &PairingHandler::pairingFailed, this, &Device::pairingHandler_pairingFailed); + connect(d->m_pairingHandler, &PairingHandler::pairingSuccessful, this, &Device::pairingHandler_pairingSuccessful); + connect(d->m_pairingHandler, &PairingHandler::unpaired, this, &Device::pairingHandler_unpaired); } Device::Device(QObject *parent, const NetworkPacket &identityPacket, DeviceLink *dl) : QObject(parent) , d(new Device::DevicePrivate(identityPacket.get(QStringLiteral("deviceId")))) { + d->m_pairingHandler = new PairingHandler(this, PairState::NotPaired); d->m_deviceName = identityPacket.get(QStringLiteral("deviceName")); d->m_allPlugins = PluginLoader::instance()->getPluginList().toSet(); @@ -94,10 +101,15 @@ Device::Device(QObject *parent, const NetworkPacket &identityPacket, DeviceLink // Register in bus QDBusConnection::sessionBus().registerObject(dbusPath(), this, QDBusConnection::ExportScriptableContents | QDBusConnection::ExportAdaptors); - connect(this, &Device::pairingError, this, &warn); + connect(this, &Device::pairingFailed, this, &warn); connect(this, &Device::reachableChanged, this, &Device::statusIconNameChanged); - connect(this, &Device::trustedChanged, this, &Device::statusIconNameChanged); + connect(this, &Device::pairStateChanged, this, &Device::statusIconNameChanged); + + connect(d->m_pairingHandler, &PairingHandler::incomingPairRequest, this, &Device::pairingHandler_incomingPairRequest); + connect(d->m_pairingHandler, &PairingHandler::pairingFailed, this, &Device::pairingHandler_pairingFailed); + connect(d->m_pairingHandler, &PairingHandler::pairingSuccessful, this, &Device::pairingHandler_pairingSuccessful); + connect(d->m_pairingHandler, &PairingHandler::unpaired, this, &Device::pairingHandler_unpaired); } Device::~Device() @@ -150,7 +162,7 @@ void Device::reloadPlugins() QHash newPluginMap, oldPluginMap = d->m_plugins; QMultiMap newPluginsByIncomingCapability; - if (isTrusted() && isReachable()) { // Do not load any plugin for unpaired devices, nor useless loading them for unreachable devices + if (isPaired() && isReachable()) { // Do not load any plugin for unpaired devices, nor useless loading them for unreachable devices PluginLoader *loader = PluginLoader::instance(); @@ -209,51 +221,60 @@ QString Device::pluginsConfigFile() const return KdeConnectConfig::instance().deviceConfigDir(id()).absoluteFilePath(QStringLiteral("config")); } -void Device::requestPair() +void Device::requestPairing() { - if (isTrusted()) { - Q_EMIT pairingError(i18n("Already paired")); - return; - } - - if (!isReachable()) { - Q_EMIT pairingError(i18n("Device not reachable")); - return; - } - - for (DeviceLink *dl : qAsConst(d->m_deviceLinks)) { - dl->userRequestsPair(); - } + qCDebug(KDECONNECT_CORE) << "Request pairing"; + d->m_pairingHandler->requestPairing(); + Q_EMIT pairStateChanged(pairStateAsInt()); } void Device::unpair() { - for (DeviceLink *dl : qAsConst(d->m_deviceLinks)) { - dl->userRequestsUnpair(); - } - KdeConnectConfig::instance().removeTrustedDevice(id()); - Q_EMIT trustedChanged(false); + qCDebug(KDECONNECT_CORE) << "Request unpairing"; + d->m_pairingHandler->unpair(); } -void Device::pairStatusChanged(DeviceLink::PairStatus status) +void Device::acceptPairing() { - if (status == DeviceLink::NotPaired) { - KdeConnectConfig::instance().removeTrustedDevice(id()); + qCDebug(KDECONNECT_CORE) << "Accept pairing"; + d->m_pairingHandler->acceptPairing(); +} - for (DeviceLink *dl : qAsConst(d->m_deviceLinks)) { - if (dl != sender()) { - dl->setPairStatus(DeviceLink::NotPaired); - } - } - } else { - KdeConnectConfig::instance().addTrustedDevice(id(), name(), type()); - } +void Device::cancelPairing() +{ + qCDebug(KDECONNECT_CORE) << "Cancel pairing"; + d->m_pairingHandler->cancelPairing(); +} +void Device::pairingHandler_incomingPairRequest() +{ + Q_ASSERT(d->m_pairingHandler->pairState() == PairState::RequestedByPeer); + Q_EMIT pairStateChanged(pairStateAsInt()); +} + +void Device::pairingHandler_pairingSuccessful() +{ + Q_ASSERT(d->m_pairingHandler->pairState() == PairState::Paired); + KdeConnectConfig::instance().addTrustedDevice(id(), name(), type()); + KdeConnectConfig::instance().setDeviceProperty(d->m_deviceId, QStringLiteral("certificate"), QString::fromLatin1(certificate().toPem())); reloadPlugins(); // Will load/unload plugins + Q_EMIT pairStateChanged(pairStateAsInt()); +} - bool isTrusted = (status == DeviceLink::Paired); - Q_EMIT trustedChanged(isTrusted); - Q_ASSERT(isTrusted == this->isTrusted()); +void Device::pairingHandler_pairingFailed(const QString &errorMessage) +{ + Q_ASSERT(d->m_pairingHandler->pairState() == PairState::NotPaired); + Q_EMIT pairingFailed(errorMessage); + Q_EMIT pairStateChanged(pairStateAsInt()); +} + +void Device::pairingHandler_unpaired() +{ + Q_ASSERT(d->m_pairingHandler->pairState() == PairState::NotPaired); + qCDebug(KDECONNECT_CORE) << "Unpaired"; + KdeConnectConfig::instance().removeTrustedDevice(id()); + reloadPlugins(); // Will load/unload plugins + Q_EMIT pairStateChanged(pairStateAsInt()); } static bool lessThan(DeviceLink *p1, DeviceLink *p2) @@ -306,56 +327,6 @@ void Device::addLink(const NetworkPacket &identityPacket, DeviceLink *link) if (d->m_deviceLinks.size() == 1) { Q_EMIT reachableChanged(true); } - - connect(link, &DeviceLink::pairStatusChanged, this, &Device::pairStatusChanged); - connect(link, &DeviceLink::pairingRequest, this, &Device::addPairingRequest); - connect(link, &DeviceLink::pairingRequestExpired, this, &Device::removePairingRequest); - connect(link, &DeviceLink::pairingError, this, &Device::pairingError); -} - -void Device::addPairingRequest(PairingHandler *handler) -{ - const bool wasEmpty = d->m_pairRequests.isEmpty(); - d->m_pairRequests.insert(handler); - - if (wasEmpty != d->m_pairRequests.isEmpty()) - Q_EMIT hasPairingRequestsChanged(!d->m_pairRequests.isEmpty()); -} - -void Device::removePairingRequest(PairingHandler *handler) -{ - const bool wasEmpty = d->m_pairRequests.isEmpty(); - d->m_pairRequests.remove(handler); - - if (wasEmpty != d->m_pairRequests.isEmpty()) - Q_EMIT hasPairingRequestsChanged(!d->m_pairRequests.isEmpty()); -} - -bool Device::hasPairingRequests() const -{ - return !d->m_pairRequests.isEmpty(); -} - -void Device::acceptPairing() -{ - if (d->m_pairRequests.isEmpty()) - qWarning() << "no pair requests to accept!"; - - // copying because the pairing handler will be removed upon accept - const auto prCopy = d->m_pairRequests; - for (auto ph : prCopy) - ph->acceptPairing(); -} - -void Device::rejectPairing() -{ - if (d->m_pairRequests.isEmpty()) - qWarning() << "no pair requests to reject!"; - - // copying because the pairing handler will be removed upon reject - const auto prCopy = d->m_pairRequests; - for (auto ph : prCopy) - ph->rejectPairing(); } void Device::linkDestroyed(QObject *o) @@ -377,8 +348,7 @@ void Device::removeLink(DeviceLink *link) bool Device::sendPacket(NetworkPacket &np) { - Q_ASSERT(np.type() != PACKET_TYPE_PAIR); - Q_ASSERT(isTrusted()); + Q_ASSERT(isPaired() || np.type() == PACKET_TYPE_PAIR); // Maybe we could block here any packet that is not an identity or a pairing packet to prevent sending non encrypted data for (DeviceLink *dl : qAsConst(d->m_deviceLinks)) { @@ -391,8 +361,9 @@ bool Device::sendPacket(NetworkPacket &np) void Device::privateReceivedPacket(const NetworkPacket &np) { - Q_ASSERT(np.type() != PACKET_TYPE_PAIR); - if (isTrusted()) { + if (np.type() == PACKET_TYPE_PAIR) { + d->m_pairingHandler->packetReceived(np); + } else if (isPaired()) { const QList plugins = d->m_pluginsByIncomingCapability.values(np.type()); if (plugins.isEmpty()) { qWarning() << "discarding unsupported packet" << np.type() << "for" << name(); @@ -406,11 +377,33 @@ void Device::privateReceivedPacket(const NetworkPacket &np) } } -bool Device::isTrusted() const +PairState Device::pairState() const { - return KdeConnectConfig::instance().trustedDevices().contains(id()); + return d->m_pairingHandler->pairState(); } +int Device::pairStateAsInt() const +{ + return (int)pairState(); +} + +bool Device::isPaired() const +{ + return d->m_pairingHandler->pairState() == PairState::Paired; +} + +bool Device::isPairRequested() const +{ + return d->m_pairingHandler->pairState() == PairState::Requested; +} + + +bool Device::isPairRequestedByPeer() const +{ + return d->m_pairingHandler->pairState() == PairState::RequestedByPeer; +} + + QStringList Device::availableLinks() const { QStringList sl; @@ -421,22 +414,6 @@ QStringList Device::availableLinks() const return sl; } -void Device::cleanUnneededLinks() -{ - if (isTrusted()) { - return; - } - for (int i = 0; i < d->m_deviceLinks.size();) { - DeviceLink *dl = d->m_deviceLinks[i]; - if (!dl->linkShouldBeKeptAlive()) { - dl->deleteLater(); - d->m_deviceLinks.remove(i); - } else { - i++; - } - } -} - QHostAddress Device::getLocalIpAddress() const { for (DeviceLink *dl : qAsConst(d->m_deviceLinks)) { @@ -480,7 +457,7 @@ QString Device::type2str(Device::DeviceType deviceType) QString Device::statusIconName() const { - return iconForStatus(isReachable(), isTrusted()); + return iconForStatus(isReachable(), isPaired()); } QString Device::iconName() const diff --git a/core/device.h b/core/device.h index 4c5c56794..f649638f4 100644 --- a/core/device.h +++ b/core/device.h @@ -13,6 +13,7 @@ #include "backends/devicelink.h" #include "networkpacket.h" +#include "pairstate.h" class DeviceLink; class KdeConnectPlugin; @@ -26,9 +27,11 @@ class KDECONNECTCORE_EXPORT Device : public QObject Q_PROPERTY(QString iconName READ iconName CONSTANT) Q_PROPERTY(QString statusIconName READ statusIconName NOTIFY statusIconNameChanged) Q_PROPERTY(bool isReachable READ isReachable NOTIFY reachableChanged) - Q_PROPERTY(bool isTrusted READ isTrusted NOTIFY trustedChanged) + Q_PROPERTY(bool isPaired READ isPaired NOTIFY pairStateChanged) + Q_PROPERTY(bool isPairRequested READ isPairRequested NOTIFY pairStateChanged) + Q_PROPERTY(bool isPairRequestedByPeer READ isPairRequestedByPeer NOTIFY pairStateChanged) + Q_PROPERTY(int pairState READ pairStateAsInt NOTIFY pairStateChanged) Q_PROPERTY(QStringList supportedPlugins READ supportedPlugins NOTIFY pluginsChanged) - Q_PROPERTY(bool hasPairingRequests READ hasPairingRequests NOTIFY hasPairingRequestsChanged) public: enum DeviceType { @@ -72,7 +75,11 @@ public: void addLink(const NetworkPacket &identityPacket, DeviceLink *); void removeLink(DeviceLink *); - Q_SCRIPTABLE bool isTrusted() const; + PairState pairState() const; + Q_SCRIPTABLE int pairStateAsInt() const; // Hack because qdbus doesn't like enums + Q_SCRIPTABLE bool isPaired() const; + Q_SCRIPTABLE bool isPairRequested() const; + Q_SCRIPTABLE bool isPairRequestedByPeer() const; Q_SCRIPTABLE QStringList availableLinks() const; virtual bool isReachable() const; @@ -86,8 +93,6 @@ public: Q_SCRIPTABLE void setPluginEnabled(const QString &pluginName, bool enabled); Q_SCRIPTABLE bool isPluginEnabled(const QString &pluginName) const; - void cleanUnneededLinks(); - int protocolVersion(); QStringList supportedPlugins() const; @@ -100,33 +105,32 @@ public Q_SLOTS: // Dbus operations public Q_SLOTS: - Q_SCRIPTABLE void requestPair(); // to all links - Q_SCRIPTABLE void unpair(); // from all links + Q_SCRIPTABLE void requestPairing(); + Q_SCRIPTABLE void unpair(); Q_SCRIPTABLE void reloadPlugins(); // from kconf Q_SCRIPTABLE void acceptPairing(); - Q_SCRIPTABLE void rejectPairing(); - Q_SCRIPTABLE bool hasPairingRequests() const; + Q_SCRIPTABLE void cancelPairing(); Q_SCRIPTABLE QString pluginIconName(const QString &pluginName); private Q_SLOTS: void privateReceivedPacket(const NetworkPacket &np); void linkDestroyed(QObject *o); - void pairStatusChanged(DeviceLink::PairStatus current); - void addPairingRequest(PairingHandler *handler); - void removePairingRequest(PairingHandler *handler); + + void pairingHandler_incomingPairRequest(); + void pairingHandler_pairingFailed(const QString &errorMessage); + void pairingHandler_pairingSuccessful(); + void pairingHandler_unpaired(); Q_SIGNALS: Q_SCRIPTABLE void pluginsChanged(); Q_SCRIPTABLE void reachableChanged(bool reachable); - Q_SCRIPTABLE void trustedChanged(bool trusted); - Q_SCRIPTABLE void pairingError(const QString &error); + Q_SCRIPTABLE void pairStateChanged(int pairState); // Hack because qdbus doesn't like enums + Q_SCRIPTABLE void pairingFailed(const QString &error); Q_SCRIPTABLE void nameChanged(const QString &name); Q_SCRIPTABLE void typeChanged(const QString &type); Q_SCRIPTABLE void statusIconNameChanged(); - Q_SCRIPTABLE void hasPairingRequestsChanged(bool hasPairingRequests); - private: // Methods static DeviceType str2type(const QString &deviceType); static QString type2str(DeviceType deviceType); diff --git a/core/pairstate.h b/core/pairstate.h new file mode 100644 index 000000000..eeb1a76d8 --- /dev/null +++ b/core/pairstate.h @@ -0,0 +1,18 @@ +/** + * SPDX-FileCopyrightText: 2023 Albert Vaca + * + * SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL + */ + + +#ifndef PAIR_STATE_H +#define PAIR_STATE_H + +enum class PairState { + NotPaired, + Requested, + RequestedByPeer, + Paired, +}; + +#endif diff --git a/daemon/kdeconnectd.cpp b/daemon/kdeconnectd.cpp index 42c81c749..521e5efd3 100644 --- a/daemon/kdeconnectd.cpp +++ b/daemon/kdeconnectd.cpp @@ -44,7 +44,7 @@ public: void askPairingConfirmation(Device *device) override { KNotification *notification = new KNotification(QStringLiteral("pairingRequest"), KNotification::NotificationFlag::Persistent); - QTimer::singleShot(PairingHandler::pairingTimeoutMsec(), notification, &KNotification::close); + QTimer::singleShot(PairingHandler::pairingTimeoutMsec, notification, &KNotification::close); notification->setIconName(QStringLiteral("dialog-information")); notification->setComponentName(QStringLiteral("kdeconnect")); notification->setTitle(QStringLiteral("KDE Connect")); @@ -53,7 +53,7 @@ public: notification->setDefaultAction(i18n("Open")); notification->setActions(QStringList() << i18n("Accept") << i18n("Reject") << i18n("View key")); connect(notification, &KNotification::action1Activated, device, &Device::acceptPairing); - connect(notification, &KNotification::action2Activated, device, &Device::rejectPairing); + connect(notification, &KNotification::action2Activated, device, &Device::cancelPairing); QString deviceId = device->id(); auto openSettings = [deviceId, notification] { OpenConfig oc; diff --git a/indicator/main.cpp b/indicator/main.cpp index 78386bb78..6d2349c59 100644 --- a/indicator/main.cpp +++ b/indicator/main.cpp @@ -105,7 +105,7 @@ int main(int argc, char **argv) DeviceDbusInterface *dev = new DeviceDbusInterface(req, menu); auto pairMenu = menu->addMenu(dev->name()); pairMenu->addAction(i18n("Pair"), dev, &DeviceDbusInterface::acceptPairing); - pairMenu->addAction(i18n("Reject"), dev, &DeviceDbusInterface::rejectPairing); + pairMenu->addAction(i18n("Reject"), dev, &DeviceDbusInterface::cancelPairing); } } // Add quit menu diff --git a/interfaces/dbusinterfaces.cpp b/interfaces/dbusinterfaces.cpp index 8d608cad6..5c1058f5e 100644 --- a/interfaces/dbusinterfaces.cpp +++ b/interfaces/dbusinterfaces.cpp @@ -39,10 +39,9 @@ DeviceDbusInterface::DeviceDbusInterface(const QString &id, QObject *parent) parent) , m_id(id) { - connect(this, &OrgKdeKdeconnectDeviceInterface::trustedChanged, this, &DeviceDbusInterface::trustedChangedProxy); + connect(this, &OrgKdeKdeconnectDeviceInterface::pairStateChanged, this, &DeviceDbusInterface::pairStateChangedProxy); connect(this, &OrgKdeKdeconnectDeviceInterface::reachableChanged, this, &DeviceDbusInterface::reachableChangedProxy); connect(this, &OrgKdeKdeconnectDeviceInterface::nameChanged, this, &DeviceDbusInterface::nameChangedProxy); - connect(this, &OrgKdeKdeconnectDeviceInterface::hasPairingRequestsChanged, this, &DeviceDbusInterface::hasPairingRequestsChangedProxy); } DeviceDbusInterface::~DeviceDbusInterface() diff --git a/interfaces/dbusinterfaces.h b/interfaces/dbusinterfaces.h index ff23cb5a9..b135b257b 100644 --- a/interfaces/dbusinterfaces.h +++ b/interfaces/dbusinterfaces.h @@ -56,9 +56,11 @@ class KDECONNECTINTERFACES_EXPORT DeviceDbusInterface : public OrgKdeKdeconnectD // TODO: Workaround because OrgKdeKdeconnectDeviceInterface is not generating // the signals for the properties Q_PROPERTY(bool isReachable READ isReachable NOTIFY reachableChangedProxy) - Q_PROPERTY(bool isTrusted READ isTrusted NOTIFY trustedChangedProxy) + Q_PROPERTY(bool isPaired READ isPaired NOTIFY pairStateChangedProxy) + Q_PROPERTY(bool isPairRequested READ isPairRequested NOTIFY pairStateChangedProxy) + Q_PROPERTY(bool isPairRequestedByPeer READ isPairRequestedByPeer NOTIFY pairStateChangedProxy) + Q_PROPERTY(int pairState READ pairState NOTIFY pairStateChangedProxy) Q_PROPERTY(QString name READ name NOTIFY nameChangedProxy) - Q_PROPERTY(bool hasPairingRequests READ hasPairingRequests NOTIFY hasPairingRequestsChangedProxy) public: explicit DeviceDbusInterface(const QString &deviceId, QObject *parent = nullptr); @@ -69,9 +71,8 @@ public: Q_SIGNALS: void nameChangedProxy(const QString &name); - void trustedChangedProxy(bool paired); + void pairStateChangedProxy(int pairState); void reachableChangedProxy(bool reachable); - void hasPairingRequestsChangedProxy(bool); private: const QString m_id; diff --git a/interfaces/devicesmodel.cpp b/interfaces/devicesmodel.cpp index 6b970df65..9763e2152 100644 --- a/interfaces/devicesmodel.cpp +++ b/interfaces/devicesmodel.cpp @@ -43,7 +43,6 @@ DevicesModel::DevicesModel(QObject *parent) connect(watcher, &QDBusServiceWatcher::serviceRegistered, this, &DevicesModel::refreshDeviceList); connect(watcher, &QDBusServiceWatcher::serviceUnregistered, this, &DevicesModel::clearDevices); - // refresh the view, acquireDiscoveryMode if necessary setDisplayFilter(NoFilter); } @@ -60,7 +59,6 @@ QHash DevicesModel::roleNames() const DevicesModel::~DevicesModel() { - m_dbusInterface->releaseDiscoveryMode(*s_keyId); } int DevicesModel::rowForDevice(const QString &id) const @@ -140,12 +138,6 @@ void DevicesModel::setDisplayFilter(int flags) { m_displayFilter = (StatusFilterFlag)flags; - const bool reachableNeeded = (m_displayFilter & StatusFilterFlag::Reachable); - if (reachableNeeded) - m_dbusInterface->acquireDiscoveryMode(*s_keyId); - else - m_dbusInterface->releaseDiscoveryMode(*s_keyId); - refreshDeviceList(); } @@ -239,7 +231,7 @@ QVariant DevicesModel::data(const QModelIndex &index, int role) const case NameModelRole: return device->name(); case Qt::ToolTipRole: { - bool trusted = device->isTrusted(); + bool trusted = device->isPaired(); bool reachable = device->isReachable(); QString status = reachable ? (trusted ? i18n("Device trusted and connected") : i18n("Device not trusted")) : i18n("Device disconnected"); return status; @@ -249,7 +241,7 @@ QVariant DevicesModel::data(const QModelIndex &index, int role) const if (device->isReachable()) { status |= StatusFilterFlag::Reachable; } - if (device->isTrusted()) { + if (device->isPaired()) { status |= StatusFilterFlag::Paired; } return status; @@ -287,5 +279,5 @@ bool DevicesModel::passesFilter(DeviceDbusInterface *dev) const bool onlyPaired = (m_displayFilter & StatusFilterFlag::Paired); bool onlyReachable = (m_displayFilter & StatusFilterFlag::Reachable); - return !((onlyReachable && !dev->isReachable()) || (onlyPaired && !dev->isTrusted())); + return !((onlyReachable && !dev->isReachable()) || (onlyPaired && !dev->isPaired())); } diff --git a/kcm/kcm.cpp b/kcm/kcm.cpp index c8629a698..5ed77385d 100644 --- a/kcm/kcm.cpp +++ b/kcm/kcm.cpp @@ -84,8 +84,9 @@ KdeConnectKcm::KdeConnectKcm(QWidget *parent, const QVariantList &args) connect(devicesModel, &QAbstractItemModel::dataChanged, this, &KdeConnectKcm::resetSelection); connect(kcmUi->deviceList->selectionModel(), &QItemSelectionModel::currentChanged, this, &KdeConnectKcm::deviceSelected); connect(kcmUi->accept_button, &QAbstractButton::clicked, this, &KdeConnectKcm::acceptPairing); - connect(kcmUi->reject_button, &QAbstractButton::clicked, this, &KdeConnectKcm::rejectPairing); - connect(kcmUi->pair_button, &QAbstractButton::clicked, this, &KdeConnectKcm::requestPair); + connect(kcmUi->reject_button, &QAbstractButton::clicked, this, &KdeConnectKcm::cancelPairing); + connect(kcmUi->cancel_button, &QAbstractButton::clicked, this, &KdeConnectKcm::cancelPairing); + connect(kcmUi->pair_button, &QAbstractButton::clicked, this, &KdeConnectKcm::requestPairing); connect(kcmUi->unpair_button, &QAbstractButton::clicked, this, &KdeConnectKcm::unpair); connect(kcmUi->ping_button, &QAbstractButton::clicked, this, &KdeConnectKcm::sendPing); connect(kcmUi->refresh_button, &QAbstractButton::clicked, this, &KdeConnectKcm::refresh); @@ -93,8 +94,6 @@ KdeConnectKcm::KdeConnectKcm(QWidget *parent, const QVariantList &args) connect(kcmUi->renameDone_button, &QAbstractButton::clicked, this, &KdeConnectKcm::renameDone); connect(kcmUi->renameShow_button, &QAbstractButton::clicked, this, &KdeConnectKcm::renameShow); - daemon->acquireDiscoveryMode(createId()); - #if KCMUTILS_VERSION >= QT_VERSION_CHECK(5, 45, 0) if (!args.isEmpty() && args.first().type() == QVariant::String) { @@ -147,13 +146,11 @@ void KdeConnectKcm::setRenameMode(bool b) KdeConnectKcm::~KdeConnectKcm() { - daemon->releaseDiscoveryMode(createId()); delete kcmUi; } void KdeConnectKcm::refresh() { - daemon->acquireDiscoveryMode(createId()); daemon->forceOnNetworkChange(); } @@ -191,23 +188,8 @@ void KdeConnectKcm::deviceSelected(const QModelIndex ¤t) resetDeviceView(); connect(currentDevice, SIGNAL(pluginsChanged()), this, SLOT(resetCurrentDevice())); - connect(currentDevice, SIGNAL(trustedChanged(bool)), this, SLOT(trustedChanged(bool))); - connect(currentDevice, SIGNAL(pairingError(QString)), this, SLOT(pairingFailed(QString))); - connect(currentDevice, &DeviceDbusInterface::hasPairingRequestsChangedProxy, this, &KdeConnectKcm::currentDevicePairingChanged); -} - -void KdeConnectKcm::currentDevicePairingChanged(bool pairing) -{ - if (pairing) { - setCurrentDeviceTrusted(RequestedByPeer); - } else { - setWhenAvailable( - currentDevice->isTrusted(), - [this](bool trusted) { - setCurrentDeviceTrusted(trusted ? Trusted : NotTrusted); - }, - this); - } + connect(currentDevice, SIGNAL(pairingFailed(QString)), this, SLOT(pairingFailed(QString))); + connect(currentDevice, &DeviceDbusInterface::pairStateChangedProxy, this, &KdeConnectKcm::setCurrentDevicePairState); } void KdeConnectKcm::resetCurrentDevice() @@ -225,17 +207,9 @@ void KdeConnectKcm::resetDeviceView() kcmUi->name_label->setText(currentDevice->name()); setWhenAvailable( - currentDevice->isTrusted(), - [this](bool trusted) { - if (trusted) - setCurrentDeviceTrusted(Trusted); - else - setWhenAvailable( - currentDevice->hasPairingRequests(), - [this](bool haspr) { - setCurrentDeviceTrusted(haspr ? RequestedByPeer : NotTrusted); - }, - this); + currentDevice->pairStateAsInt(), + [this](int pairStateAsInt) { + setCurrentDevicePairState(pairStateAsInt); }, this); @@ -257,7 +231,7 @@ void KdeConnectKcm::resetDeviceView() connect(kcmUi->pluginSelector, &KPluginWidget::changed, this, &KdeConnectKcm::pluginsConfigChanged); } -void KdeConnectKcm::requestPair() +void KdeConnectKcm::requestPairing() { if (!currentDevice) { return; @@ -265,9 +239,7 @@ void KdeConnectKcm::requestPair() kcmUi->messages->hide(); - setCurrentDeviceTrusted(Requested); - - currentDevice->requestPair(); + currentDevice->requestPairing(); } void KdeConnectKcm::unpair() @@ -276,7 +248,6 @@ void KdeConnectKcm::unpair() return; } - setCurrentDeviceTrusted(NotTrusted); currentDevice->unpair(); } @@ -289,13 +260,13 @@ void KdeConnectKcm::acceptPairing() currentDevice->acceptPairing(); } -void KdeConnectKcm::rejectPairing() +void KdeConnectKcm::cancelPairing() { if (!currentDevice) { return; } - currentDevice->rejectPairing(); + currentDevice->cancelPairing(); } void KdeConnectKcm::pairingFailed(const QString &error) @@ -303,38 +274,32 @@ void KdeConnectKcm::pairingFailed(const QString &error) if (sender() != currentDevice) return; - setCurrentDeviceTrusted(NotTrusted); - kcmUi->messages->setText(i18n("Error trying to pair: %1", error)); kcmUi->messages->animatedShow(); } -void KdeConnectKcm::trustedChanged(bool trusted) -{ - DeviceDbusInterface *senderDevice = (DeviceDbusInterface *)sender(); - if (senderDevice == currentDevice) - setCurrentDeviceTrusted(trusted ? Trusted : NotTrusted); -} -void KdeConnectKcm::setCurrentDeviceTrusted(KdeConnectKcm::TrustStatus trusted) +void KdeConnectKcm::setCurrentDevicePairState(int pairStateAsInt) { - kcmUi->accept_button->setVisible(trusted == RequestedByPeer); - kcmUi->reject_button->setVisible(trusted == RequestedByPeer); - kcmUi->pair_button->setVisible(trusted == NotTrusted); - kcmUi->unpair_button->setVisible(trusted == Trusted); - kcmUi->progressBar->setVisible(trusted == Requested); - kcmUi->ping_button->setVisible(trusted == Trusted); - switch (trusted) { - case Trusted: + PairState state = (PairState)pairStateAsInt; // Hack because qdbus doesn't like enums + kcmUi->accept_button->setVisible(state == PairState::RequestedByPeer); + kcmUi->reject_button->setVisible(state == PairState::RequestedByPeer); + kcmUi->cancel_button->setVisible(state == PairState::Requested); + kcmUi->pair_button->setVisible(state == PairState::NotPaired); + kcmUi->unpair_button->setVisible(state == PairState::Paired); + kcmUi->progressBar->setVisible(state == PairState::Requested); + kcmUi->ping_button->setVisible(state == PairState::Paired); + switch (state) { + case PairState::Paired: kcmUi->status_label->setText(i18n("(paired)")); break; - case NotTrusted: + case PairState::NotPaired: kcmUi->status_label->setText(i18n("(not paired)")); break; - case RequestedByPeer: + case PairState::RequestedByPeer: kcmUi->status_label->setText(i18n("(incoming pair request)")); break; - case Requested: + case PairState::Requested: kcmUi->status_label->setText(i18n("(pairing requested)")); break; } diff --git a/kcm/kcm.h b/kcm/kcm.h index d8644a566..31e6d4504 100644 --- a/kcm/kcm.h +++ b/kcm/kcm.h @@ -10,6 +10,8 @@ #include #include +#include + class QModelIndex; class DeviceDbusInterface; class DaemonDbusInterface; @@ -35,24 +37,22 @@ private: private Q_SLOTS: void deviceSelected(const QModelIndex ¤t); - void requestPair(); + void requestPairing(); void pluginsConfigChanged(); void sendPing(); void resetSelection(); - void trustedChanged(bool); void pairingFailed(const QString &error); void refresh(); void renameShow(); void renameDone(); void setRenameMode(bool b); void resetCurrentDevice(); - void currentDevicePairingChanged(bool pairing); + void setCurrentDevicePairState(int pairStateAsInt); void acceptPairing(); - void rejectPairing(); + void cancelPairing(); + private: - enum TrustStatus { NotTrusted, Requested, RequestedByPeer, Trusted }; - void setCurrentDeviceTrusted(TrustStatus trusted); void resetDeviceView(); Ui::KdeConnectKcmUi *kcmUi; diff --git a/kcm/kcm.ui b/kcm/kcm.ui index d2fa528d2..d2901d58a 100644 --- a/kcm/kcm.ui +++ b/kcm/kcm.ui @@ -251,6 +251,19 @@ + + + + + 0 + 0 + + + + Cancel + + + diff --git a/kio/kiokdeconnect.cpp b/kio/kiokdeconnect.cpp index 6c0de368f..b3457257b 100644 --- a/kio/kiokdeconnect.cpp +++ b/kio/kiokdeconnect.cpp @@ -137,7 +137,7 @@ KIO::WorkerResult KioKdeconnect::listDevice(const QString &device) DeviceDbusInterface dev(device); - if (!dev.isTrusted()) { + if (!dev.isPaired()) { return KIO::WorkerResult::fail(KIO::ERR_WORKER_DEFINED, i18n("%0 is not paired").arg(dev.name())); } diff --git a/tests/pluginloadtest.cpp b/tests/pluginloadtest.cpp index e237ba9dd..07597a2ca 100644 --- a/tests/pluginloadtest.cpp +++ b/tests/pluginloadtest.cpp @@ -36,12 +36,11 @@ private Q_SLOTS: } Device *d = nullptr; - m_daemon->acquireDiscoveryMode(QStringLiteral("plugintest")); const QList devicesList = m_daemon->devicesList(); for (Device *id : devicesList) { if (id->isReachable()) { - if (!id->isTrusted()) - id->requestPair(); + if (!id->isPaired()) + id->requestPairing(); d = id; break; } @@ -49,14 +48,13 @@ private Q_SLOTS: if (d == nullptr) { QFAIL("Unable to determine device"); } - m_daemon->releaseDiscoveryMode(QStringLiteral("plugintest")); if (!d->loadedPlugins().contains(QStringLiteral("kdeconnect_remotecontrol"))) { QSKIP("kdeconnect_remotecontrol is required for this test"); } QVERIFY(d); - QVERIFY(d->isTrusted()); + QVERIFY(d->isPaired()); QVERIFY(d->isReachable()); d->setPluginEnabled(QStringLiteral("kdeconnect_mousepad"), false); diff --git a/tests/sendfiletest.cpp b/tests/sendfiletest.cpp index 3f7b04432..d17dc2732 100644 --- a/tests/sendfiletest.cpp +++ b/tests/sendfiletest.cpp @@ -40,22 +40,20 @@ private Q_SLOTS: QFAIL("No links available, but loopback should have been provided by the test"); } - m_daemon->acquireDiscoveryMode(QStringLiteral("test")); Device *d = nullptr; const QList devicesList = m_daemon->devicesList(); for (Device *id : devicesList) { if (id->isReachable()) { - if (!id->isTrusted()) - id->requestPair(); + if (!id->isPaired()) + id->requestPairing(); d = id; } } if (d == nullptr) { QFAIL("Unable to determine device"); } - m_daemon->releaseDiscoveryMode(QStringLiteral("test")); QCOMPARE(d->isReachable(), true); - QCOMPARE(d->isTrusted(), true); + QCOMPARE(d->isPaired(), true); QByteArray content("12312312312313213123213123");