Refactor PairingHandler
We now have a single PairingHandler for all types of links. The implementation now is more aligned with the one for Android.
This commit is contained in:
parent
85cc644024
commit
064ddfa3fe
35 changed files with 368 additions and 895 deletions
|
@ -21,12 +21,12 @@ Kirigami.ScrollablePage {
|
||||||
iconName:"network-disconnect"
|
iconName:"network-disconnect"
|
||||||
onTriggered: root.currentDevice.unpair()
|
onTriggered: root.currentDevice.unpair()
|
||||||
text: i18nd("kdeconnect-app", "Unpair")
|
text: i18nd("kdeconnect-app", "Unpair")
|
||||||
visible: root.currentDevice.isTrusted
|
visible: root.currentDevice.isPaired
|
||||||
},
|
},
|
||||||
Kirigami.Action {
|
Kirigami.Action {
|
||||||
iconName:"hands-free"
|
iconName:"hands-free"
|
||||||
text: i18nd("kdeconnect-app", "Send Ping")
|
text: i18nd("kdeconnect-app", "Send Ping")
|
||||||
visible: root.currentDevice.isTrusted && root.currentDevice.isReachable
|
visible: root.currentDevice.isPaired && root.currentDevice.isReachable
|
||||||
onTriggered: {
|
onTriggered: {
|
||||||
root.currentDevice.pluginCall("ping", "sendPing");
|
root.currentDevice.pluginCall("ping", "sendPing");
|
||||||
}
|
}
|
||||||
|
@ -34,7 +34,7 @@ Kirigami.ScrollablePage {
|
||||||
Kirigami.Action {
|
Kirigami.Action {
|
||||||
iconName: "settings-configure"
|
iconName: "settings-configure"
|
||||||
text: i18n("Plugin Settings")
|
text: i18n("Plugin Settings")
|
||||||
visible: root.currentDevice.isTrusted && root.currentDevice.isReachable
|
visible: root.currentDevice.isPaired && root.currentDevice.isReachable
|
||||||
onTriggered: {
|
onTriggered: {
|
||||||
pageStack.push(
|
pageStack.push(
|
||||||
Qt.resolvedUrl("PluginSettings.qml"),
|
Qt.resolvedUrl("PluginSettings.qml"),
|
||||||
|
@ -116,17 +116,17 @@ Kirigami.ScrollablePage {
|
||||||
Kirigami.PlaceholderMessage {
|
Kirigami.PlaceholderMessage {
|
||||||
text: i18nd("kdeconnect-app", "This device is not paired")
|
text: i18nd("kdeconnect-app", "This device is not paired")
|
||||||
anchors.centerIn: parent
|
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 {
|
helpfulAction: Kirigami.Action {
|
||||||
text: i18nd("kdeconnect-app", "Pair")
|
text: i18nd("kdeconnect-app", "Pair")
|
||||||
icon.name:"network-connect"
|
icon.name:"network-connect"
|
||||||
onTriggered: root.currentDevice.requestPair()
|
onTriggered: root.currentDevice.requestPairing()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Kirigami.PlaceholderMessage {
|
Kirigami.PlaceholderMessage {
|
||||||
text: i18n("Pair requested")
|
text: i18n("Pair requested")
|
||||||
visible: root.currentDevice && root.currentDevice.hasPairingRequests
|
visible: root.currentDevice && root.currentDevice.isPairRequestedByPeer
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
spacing: Kirigami.Units.largeSpacing
|
spacing: Kirigami.Units.largeSpacing
|
||||||
RowLayout {
|
RowLayout {
|
||||||
|
@ -139,7 +139,7 @@ Kirigami.ScrollablePage {
|
||||||
QQC2.Button {
|
QQC2.Button {
|
||||||
text: i18nd("kdeconnect-app", "Reject")
|
text: i18nd("kdeconnect-app", "Reject")
|
||||||
icon.name:"dialog-cancel"
|
icon.name:"dialog-cancel"
|
||||||
onClicked: root.currentDevice.rejectPairing()
|
onClicked: root.currentDevice.cancelPairing()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -93,7 +93,6 @@ int main(int argc, char **argv)
|
||||||
if (parser.isSet(QStringLiteral("a"))) {
|
if (parser.isSet(QStringLiteral("a"))) {
|
||||||
available = true;
|
available = true;
|
||||||
} else {
|
} else {
|
||||||
blockOnReply(iface.acquireDiscoveryMode(id));
|
|
||||||
QThread::sleep(2);
|
QThread::sleep(2);
|
||||||
}
|
}
|
||||||
const QStringList devices = blockOnReply<QStringList>(iface.devices(available, available));
|
const QStringList devices = blockOnReply<QStringList>(iface.devices(available, available));
|
||||||
|
@ -115,12 +114,12 @@ int main(int argc, char **argv)
|
||||||
DeviceDbusInterface deviceIface(id);
|
DeviceDbusInterface deviceIface(id);
|
||||||
QString statusInfo;
|
QString statusInfo;
|
||||||
const bool isReachable = deviceIface.isReachable();
|
const bool isReachable = deviceIface.isReachable();
|
||||||
const bool isTrusted = deviceIface.isTrusted();
|
const bool isPaired = deviceIface.isPaired();
|
||||||
if (isReachable && isTrusted) {
|
if (isReachable && isPaired) {
|
||||||
statusInfo = i18n("(paired and reachable)");
|
statusInfo = i18n("(paired and reachable)");
|
||||||
} else if (isReachable) {
|
} else if (isReachable) {
|
||||||
statusInfo = i18n("(reachable)");
|
statusInfo = i18n("(reachable)");
|
||||||
} else if (isTrusted) {
|
} else if (isPaired) {
|
||||||
statusInfo = i18n("(paired)");
|
statusInfo = i18n("(paired)");
|
||||||
}
|
}
|
||||||
QTextStream(stdout) << "- " << deviceIface.name() << ": " << deviceIface.id() << ' ' << statusInfo << Qt::endl;
|
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;
|
QTextStream(stderr) << i18n("No devices found") << Qt::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
blockOnReply(iface.releaseDiscoveryMode(id));
|
|
||||||
} else if (parser.isSet(QStringLiteral("shell-device-autocompletion"))) {
|
} else if (parser.isSet(QStringLiteral("shell-device-autocompletion"))) {
|
||||||
// Outputs a list of reachable devices in zsh autocomplete format, with the name as description
|
// Outputs a list of reachable devices in zsh autocomplete format, with the name as description
|
||||||
const QStringList devices = blockOnReply<QStringList>(iface.devices(true, false));
|
const QStringList devices = blockOnReply<QStringList>(iface.devices(true, false));
|
||||||
for (const QString &id : devices) {
|
for (const QString &id : devices) {
|
||||||
DeviceDbusInterface deviceIface(id);
|
DeviceDbusInterface deviceIface(id);
|
||||||
QString statusInfo;
|
QString statusInfo;
|
||||||
const bool isTrusted = deviceIface.isTrusted();
|
const bool isPaired = deviceIface.isPaired();
|
||||||
if (isTrusted) {
|
if (isPaired) {
|
||||||
statusInfo = i18n("(paired)");
|
statusInfo = i18n("(paired)");
|
||||||
} else {
|
} else {
|
||||||
statusInfo = i18n("(unpaired)");
|
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
|
// Device doesn't exist, go into discovery mode and wait up to 30 seconds for the device to appear
|
||||||
QEventLoop wait;
|
QEventLoop wait;
|
||||||
QTextStream(stderr) << i18n("waiting for device...") << Qt::endl;
|
QTextStream(stderr) << i18n("waiting for device...") << Qt::endl;
|
||||||
blockOnReply(iface.acquireDiscoveryMode(id));
|
|
||||||
|
|
||||||
QObject::connect(&iface, &DaemonDbusInterface::deviceAdded, &iface, [&](const QString &deviceAddedId) {
|
QObject::connect(&iface, &DaemonDbusInterface::deviceAdded, &iface, [&](const QString &deviceAddedId) {
|
||||||
if (device == deviceAddedId) {
|
if (device == deviceAddedId) {
|
||||||
|
@ -253,16 +250,15 @@ int main(int argc, char **argv)
|
||||||
|
|
||||||
if (!dev.isReachable()) {
|
if (!dev.isReachable()) {
|
||||||
QTextStream(stderr) << i18n("Device not found") << Qt::endl;
|
QTextStream(stderr) << i18n("Device not found") << Qt::endl;
|
||||||
} else if (blockOnReply<bool>(dev.isTrusted())) {
|
} else if (blockOnReply<bool>(dev.isPaired())) {
|
||||||
QTextStream(stderr) << i18n("Already paired") << Qt::endl;
|
QTextStream(stderr) << i18n("Already paired") << Qt::endl;
|
||||||
} else {
|
} else {
|
||||||
QTextStream(stderr) << i18n("Pair requested") << Qt::endl;
|
QTextStream(stderr) << i18n("Pair requested") << Qt::endl;
|
||||||
blockOnReply(dev.requestPair());
|
blockOnReply(dev.requestPairing());
|
||||||
}
|
}
|
||||||
blockOnReply(iface.releaseDiscoveryMode(id));
|
|
||||||
} else if (parser.isSet(QStringLiteral("unpair"))) {
|
} else if (parser.isSet(QStringLiteral("unpair"))) {
|
||||||
DeviceDbusInterface dev(device);
|
DeviceDbusInterface dev(device);
|
||||||
if (!dev.isTrusted()) {
|
if (!dev.isPaired()) {
|
||||||
QTextStream(stderr) << i18n("Already not paired") << Qt::endl;
|
QTextStream(stderr) << i18n("Already not paired") << Qt::endl;
|
||||||
} else {
|
} else {
|
||||||
QTextStream(stderr) << i18n("Unpaired") << Qt::endl;
|
QTextStream(stderr) << i18n("Unpaired") << Qt::endl;
|
||||||
|
|
|
@ -7,7 +7,6 @@ set(backends_kdeconnect_SRCS
|
||||||
backends/bluetooth/connectionmultiplexer.cpp
|
backends/bluetooth/connectionmultiplexer.cpp
|
||||||
backends/bluetooth/bluetoothlinkprovider.cpp
|
backends/bluetooth/bluetoothlinkprovider.cpp
|
||||||
backends/bluetooth/bluetoothdevicelink.cpp
|
backends/bluetooth/bluetoothdevicelink.cpp
|
||||||
backends/bluetooth/bluetoothpairinghandler.cpp
|
|
||||||
backends/bluetooth/bluetoothdownloadjob.cpp
|
backends/bluetooth/bluetoothdownloadjob.cpp
|
||||||
backends/bluetooth/bluetoothuploadjob.cpp
|
backends/bluetooth/bluetoothuploadjob.cpp
|
||||||
|
|
||||||
|
|
|
@ -22,7 +22,6 @@ BluetoothDeviceLink::BluetoothDeviceLink(const QString &deviceId,
|
||||||
, mSocketReader(new DeviceLineReader(socket.data(), this))
|
, mSocketReader(new DeviceLineReader(socket.data(), this))
|
||||||
, mConnection(connection)
|
, mConnection(connection)
|
||||||
, mChannel(socket)
|
, mChannel(socket)
|
||||||
, mPairingHandler(new BluetoothPairingHandler(this))
|
|
||||||
{
|
{
|
||||||
connect(mSocketReader, &DeviceLineReader::readyRead, this, &BluetoothDeviceLink::dataReceived);
|
connect(mSocketReader, &DeviceLineReader::readyRead, this, &BluetoothDeviceLink::dataReceived);
|
||||||
|
|
||||||
|
@ -51,21 +50,6 @@ bool BluetoothDeviceLink::sendPacket(NetworkPacket &np)
|
||||||
return (written != -1);
|
return (written != -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BluetoothDeviceLink::userRequestsPair()
|
|
||||||
{
|
|
||||||
mPairingHandler->requestPairing();
|
|
||||||
}
|
|
||||||
|
|
||||||
void BluetoothDeviceLink::userRequestsUnpair()
|
|
||||||
{
|
|
||||||
mPairingHandler->unpair();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool BluetoothDeviceLink::linkShouldBeKeptAlive()
|
|
||||||
{
|
|
||||||
return pairStatus() == Paired;
|
|
||||||
}
|
|
||||||
|
|
||||||
void BluetoothDeviceLink::dataReceived()
|
void BluetoothDeviceLink::dataReceived()
|
||||||
{
|
{
|
||||||
if (mSocketReader->bytesAvailable() == 0)
|
if (mSocketReader->bytesAvailable() == 0)
|
||||||
|
@ -78,12 +62,6 @@ void BluetoothDeviceLink::dataReceived()
|
||||||
NetworkPacket packet((QString()));
|
NetworkPacket packet((QString()));
|
||||||
NetworkPacket::unserialize(serializedPacket, &packet);
|
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()) {
|
if (packet.hasPayloadTransferInfo()) {
|
||||||
BluetoothDownloadJob *downloadJob = new BluetoothDownloadJob(mConnection, packet.payloadTransferInfo(), this);
|
BluetoothDownloadJob *downloadJob = new BluetoothDownloadJob(mConnection, packet.payloadTransferInfo(), this);
|
||||||
downloadJob->start();
|
downloadJob->start();
|
||||||
|
|
|
@ -14,7 +14,6 @@
|
||||||
|
|
||||||
#include "../devicelinereader.h"
|
#include "../devicelinereader.h"
|
||||||
#include "../devicelink.h"
|
#include "../devicelink.h"
|
||||||
#include "bluetoothpairinghandler.h"
|
|
||||||
|
|
||||||
class ConnectionMultiplexer;
|
class ConnectionMultiplexer;
|
||||||
class MultiplexChannel;
|
class MultiplexChannel;
|
||||||
|
@ -29,10 +28,6 @@ public:
|
||||||
virtual QString name() override;
|
virtual QString name() override;
|
||||||
bool sendPacket(NetworkPacket &np) override;
|
bool sendPacket(NetworkPacket &np) override;
|
||||||
|
|
||||||
virtual void userRequestsPair() override;
|
|
||||||
virtual void userRequestsUnpair() override;
|
|
||||||
|
|
||||||
virtual bool linkShouldBeKeptAlive() override;
|
|
||||||
QSslCertificate certificate() const override;
|
QSslCertificate certificate() const override;
|
||||||
|
|
||||||
private Q_SLOTS:
|
private Q_SLOTS:
|
||||||
|
@ -42,7 +37,6 @@ private:
|
||||||
DeviceLineReader *mSocketReader;
|
DeviceLineReader *mSocketReader;
|
||||||
ConnectionMultiplexer *mConnection;
|
ConnectionMultiplexer *mConnection;
|
||||||
QSharedPointer<MultiplexChannel> mChannel;
|
QSharedPointer<MultiplexChannel> mChannel;
|
||||||
BluetoothPairingHandler *mPairingHandler;
|
|
||||||
|
|
||||||
void sendMessage(const QString mMessage);
|
void sendMessage(const QString mMessage);
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,137 +0,0 @@
|
||||||
/**
|
|
||||||
* SPDX-FileCopyrightText: 2015 Vineet Garg <grg.vineet@gmail.com>
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "bluetoothpairinghandler.h"
|
|
||||||
|
|
||||||
#include <KLocalizedString>
|
|
||||||
|
|
||||||
#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<bool>(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);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,58 +0,0 @@
|
||||||
/**
|
|
||||||
* SPDX-FileCopyrightText: 2015 Vineet Garg <grg.vineet@gmail.com>
|
|
||||||
*
|
|
||||||
* 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 <QTimer>
|
|
||||||
|
|
||||||
// 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
|
|
|
@ -12,17 +12,9 @@ DeviceLink::DeviceLink(const QString &deviceId, LinkProvider *parent)
|
||||||
: QObject(parent)
|
: QObject(parent)
|
||||||
, m_deviceId(deviceId)
|
, m_deviceId(deviceId)
|
||||||
, m_linkProvider(parent)
|
, m_linkProvider(parent)
|
||||||
, m_pairStatus(NotPaired)
|
|
||||||
{
|
{
|
||||||
Q_ASSERT(!deviceId.isEmpty());
|
Q_ASSERT(!deviceId.isEmpty());
|
||||||
|
|
||||||
setProperty("deviceId", deviceId);
|
setProperty("deviceId", deviceId);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DeviceLink::setPairStatus(DeviceLink::PairStatus status)
|
|
||||||
{
|
|
||||||
if (m_pairStatus != status) {
|
|
||||||
m_pairStatus = status;
|
|
||||||
Q_EMIT pairStatusChanged(status);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -22,7 +22,6 @@ class DeviceLink : public QObject
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
enum PairStatus { NotPaired, Paired };
|
|
||||||
|
|
||||||
DeviceLink(const QString &deviceId, LinkProvider *parent);
|
DeviceLink(const QString &deviceId, LinkProvider *parent);
|
||||||
~DeviceLink() override = default;
|
~DeviceLink() override = default;
|
||||||
|
@ -40,35 +39,14 @@ public:
|
||||||
|
|
||||||
virtual bool sendPacket(NetworkPacket &np) = 0;
|
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;
|
virtual QSslCertificate certificate() const = 0;
|
||||||
|
|
||||||
Q_SIGNALS:
|
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);
|
void receivedPacket(const NetworkPacket &np);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const QString m_deviceId;
|
const QString m_deviceId;
|
||||||
LinkProvider *m_linkProvider;
|
LinkProvider *m_linkProvider;
|
||||||
PairStatus m_pairStatus;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -5,7 +5,6 @@ set(backends_kdeconnect_SRCS
|
||||||
backends/lan/server.cpp
|
backends/lan/server.cpp
|
||||||
backends/lan/lanlinkprovider.cpp
|
backends/lan/lanlinkprovider.cpp
|
||||||
backends/lan/landevicelink.cpp
|
backends/lan/landevicelink.cpp
|
||||||
backends/lan/lanpairinghandler.cpp
|
|
||||||
backends/lan/compositeuploadjob.cpp
|
backends/lan/compositeuploadjob.cpp
|
||||||
backends/lan/uploadjob.cpp
|
backends/lan/uploadjob.cpp
|
||||||
backends/lan/socketlinereader.cpp
|
backends/lan/socketlinereader.cpp
|
||||||
|
|
|
@ -43,7 +43,6 @@ void LanDeviceLink::reset(QSslSocket *socket, ConnectionStarted connectionSource
|
||||||
m_connectionSource = connectionSource;
|
m_connectionSource = connectionSource;
|
||||||
|
|
||||||
QString certString = KdeConnectConfig::instance().getDeviceProperty(deviceId(), QStringLiteral("certificate"));
|
QString certString = KdeConnectConfig::instance().getDeviceProperty(deviceId(), QStringLiteral("certificate"));
|
||||||
DeviceLink::setPairStatus(certString.isEmpty() ? PairStatus::NotPaired : PairStatus::Paired);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QHostAddress LanDeviceLink::hostAddress() const
|
QHostAddress LanDeviceLink::hostAddress() const
|
||||||
|
@ -109,12 +108,6 @@ void LanDeviceLink::dataReceived()
|
||||||
|
|
||||||
// qCDebug(KDECONNECT_CORE) << "LanDeviceLink dataReceived" << serializedPacket;
|
// 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<LanLinkProvider *>(provider())->incomingPairPacket(this, packet);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (packet.hasPayloadTransferInfo()) {
|
if (packet.hasPayloadTransferInfo()) {
|
||||||
// qCDebug(KDECONNECT_CORE) << "HasPayloadTransferInfo";
|
// qCDebug(KDECONNECT_CORE) << "HasPayloadTransferInfo";
|
||||||
const QVariantMap transferInfo = packet.payloadTransferInfo();
|
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<LanLinkProvider *>(provider())->userRequestsPair(deviceId());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void LanDeviceLink::userRequestsUnpair()
|
|
||||||
{
|
|
||||||
qobject_cast<LanLinkProvider *>(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
|
QSslCertificate LanDeviceLink::certificate() const
|
||||||
{
|
{
|
||||||
return m_socketLineReader->peerCertificate();
|
return m_socketLineReader->peerCertificate();
|
||||||
|
|
|
@ -33,13 +33,6 @@ public:
|
||||||
QString name() override;
|
QString name() override;
|
||||||
bool sendPacket(NetworkPacket &np) override;
|
bool sendPacket(NetworkPacket &np) override;
|
||||||
|
|
||||||
void userRequestsPair() override;
|
|
||||||
void userRequestsUnpair() override;
|
|
||||||
|
|
||||||
void setPairStatus(PairStatus status) override;
|
|
||||||
|
|
||||||
bool linkShouldBeKeptAlive() override;
|
|
||||||
|
|
||||||
QHostAddress hostAddress() const;
|
QHostAddress hostAddress() const;
|
||||||
QSslCertificate certificate() const override;
|
QSslCertificate certificate() const override;
|
||||||
|
|
||||||
|
|
|
@ -32,7 +32,6 @@
|
||||||
#include "daemon.h"
|
#include "daemon.h"
|
||||||
#include "kdeconnectconfig.h"
|
#include "kdeconnectconfig.h"
|
||||||
#include "landevicelink.h"
|
#include "landevicelink.h"
|
||||||
#include "lanpairinghandler.h"
|
|
||||||
#include "qtcompat_p.h"
|
#include "qtcompat_p.h"
|
||||||
|
|
||||||
#define MIN_VERSION_WITH_SSL_SUPPORT 6
|
#define MIN_VERSION_WITH_SSL_SUPPORT 6
|
||||||
|
@ -537,10 +536,6 @@ void LanLinkProvider::deviceLinkDestroyed(QObject *destroyedDeviceLink)
|
||||||
if (linkIterator != m_links.end()) {
|
if (linkIterator != m_links.end()) {
|
||||||
Q_ASSERT(linkIterator.value() == destroyedDeviceLink);
|
Q_ASSERT(linkIterator.value() == destroyedDeviceLink);
|
||||||
m_links.erase(linkIterator);
|
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);
|
connect(deviceLink, &QObject::destroyed, this, &LanLinkProvider::deviceLinkDestroyed);
|
||||||
m_links[deviceId] = deviceLink;
|
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);
|
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);
|
|
||||||
}
|
|
||||||
|
|
|
@ -19,7 +19,6 @@
|
||||||
#include "landevicelink.h"
|
#include "landevicelink.h"
|
||||||
#include "server.h"
|
#include "server.h"
|
||||||
|
|
||||||
class LanPairingHandler;
|
|
||||||
class KDECONNECTCORE_EXPORT LanLinkProvider : public LinkProvider
|
class KDECONNECTCORE_EXPORT LanLinkProvider : public LinkProvider
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
@ -42,10 +41,6 @@ public:
|
||||||
return PRIORITY_HIGH;
|
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 configureSslSocket(QSslSocket *socket, const QString &deviceId, bool isDeviceTrusted);
|
||||||
static void configureSocket(QSslSocket *socket);
|
static void configureSocket(QSslSocket *socket);
|
||||||
|
|
||||||
|
@ -73,8 +68,6 @@ private Q_SLOTS:
|
||||||
void broadcastToNetwork();
|
void broadcastToNetwork();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
LanPairingHandler *createPairingHandler(DeviceLink *link);
|
|
||||||
|
|
||||||
void onNetworkConfigurationChanged(const QNetworkConfiguration &config);
|
void onNetworkConfigurationChanged(const QNetworkConfiguration &config);
|
||||||
void addLink(const QString &deviceId, QSslSocket *socket, NetworkPacket *receivedPacket, LanDeviceLink::ConnectionStarted connectionOrigin);
|
void addLink(const QString &deviceId, QSslSocket *socket, NetworkPacket *receivedPacket, LanDeviceLink::ConnectionStarted connectionOrigin);
|
||||||
QList<QHostAddress> getBroadcastAddresses();
|
QList<QHostAddress> getBroadcastAddresses();
|
||||||
|
@ -88,7 +81,6 @@ private:
|
||||||
quint16 m_udpListenPort;
|
quint16 m_udpListenPort;
|
||||||
|
|
||||||
QMap<QString, LanDeviceLink *> m_links;
|
QMap<QString, LanDeviceLink *> m_links;
|
||||||
QMap<QString, LanPairingHandler *> m_pairingHandlers;
|
|
||||||
|
|
||||||
struct PendingConnect {
|
struct PendingConnect {
|
||||||
NetworkPacket *np;
|
NetworkPacket *np;
|
||||||
|
|
|
@ -1,129 +0,0 @@
|
||||||
/**
|
|
||||||
* SPDX-FileCopyrightText: 2015 Vineet Garg <grg.vineet@gmail.com>
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "lanpairinghandler.h"
|
|
||||||
|
|
||||||
#include <KLocalizedString>
|
|
||||||
|
|
||||||
#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<bool>(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);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,61 +0,0 @@
|
||||||
/**
|
|
||||||
* SPDX-FileCopyrightText: 2015 Vineet Garg <grg.vineet@gmail.com>
|
|
||||||
*
|
|
||||||
* 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 <QObject>
|
|
||||||
#include <QTimer>
|
|
||||||
|
|
||||||
#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
|
|
|
@ -21,15 +21,6 @@ public:
|
||||||
QString name() override;
|
QString name() override;
|
||||||
bool sendPacket(NetworkPacket &np) override;
|
bool sendPacket(NetworkPacket &np) override;
|
||||||
|
|
||||||
void userRequestsPair() override
|
|
||||||
{
|
|
||||||
setPairStatus(Paired);
|
|
||||||
}
|
|
||||||
void userRequestsUnpair() override
|
|
||||||
{
|
|
||||||
setPairStatus(NotPaired);
|
|
||||||
}
|
|
||||||
|
|
||||||
QSslCertificate certificate() const override
|
QSslCertificate certificate() const override
|
||||||
{
|
{
|
||||||
return QSslCertificate();
|
return QSslCertificate();
|
||||||
|
|
|
@ -6,19 +6,138 @@
|
||||||
|
|
||||||
#include "pairinghandler.h"
|
#include "pairinghandler.h"
|
||||||
|
|
||||||
PairingHandler::PairingHandler(DeviceLink *parent)
|
#include "core_debug.h"
|
||||||
|
|
||||||
|
#include <KLocalizedString>
|
||||||
|
|
||||||
|
PairingHandler::PairingHandler(Device *parent, PairState initialState)
|
||||||
: QObject(parent)
|
: 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_pairingTimeout.stop();
|
||||||
m_deviceLink = dl;
|
bool wantsPair = np.get<bool>(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();
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,48 +7,48 @@
|
||||||
#ifndef KDECONNECT_PAIRINGHANDLER_H
|
#ifndef KDECONNECT_PAIRINGHANDLER_H
|
||||||
#define KDECONNECT_PAIRINGHANDLER_H
|
#define KDECONNECT_PAIRINGHANDLER_H
|
||||||
|
|
||||||
#include "devicelink.h"
|
#include "device.h"
|
||||||
#include "networkpacket.h"
|
#include "networkpacket.h"
|
||||||
|
#include "pairstate.h"
|
||||||
|
|
||||||
/*
|
#include <QTimer>
|
||||||
* 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
|
|
||||||
*/
|
|
||||||
|
|
||||||
class KDECONNECTCORE_EXPORT PairingHandler : public QObject
|
class KDECONNECTCORE_EXPORT PairingHandler : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
PairingHandler(DeviceLink *parent);
|
const static int pairingTimeoutMsec = 30 * 1000; // 30 seconds of timeout
|
||||||
|
|
||||||
|
PairingHandler(Device *parent, PairState initialState);
|
||||||
~PairingHandler() override = default;
|
~PairingHandler() override = default;
|
||||||
|
|
||||||
DeviceLink *deviceLink() const;
|
void packetReceived(const NetworkPacket &np);
|
||||||
void setDeviceLink(DeviceLink *dl);
|
|
||||||
|
|
||||||
virtual void packetReceived(const NetworkPacket &np) = 0;
|
PairState pairState() { return m_pairState; }
|
||||||
virtual void unpair() = 0;
|
|
||||||
static int pairingTimeoutMsec()
|
|
||||||
{
|
|
||||||
return 30 * 1000;
|
|
||||||
} // 30 seconds of timeout (default), subclasses that use different values should override
|
|
||||||
|
|
||||||
public Q_SLOTS:
|
public Q_SLOTS:
|
||||||
virtual bool requestPairing() = 0;
|
bool requestPairing();
|
||||||
virtual bool acceptPairing() = 0;
|
bool acceptPairing();
|
||||||
virtual void rejectPairing() = 0;
|
void cancelPairing();
|
||||||
|
void unpair();
|
||||||
|
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
void pairingError(const QString &errorMessage);
|
void incomingPairRequest();
|
||||||
|
void pairingFailed(const QString &errorMessage);
|
||||||
|
void pairingSuccessful();
|
||||||
|
void unpaired();
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
DeviceLink *m_deviceLink;
|
void pairingDone();
|
||||||
|
|
||||||
|
QTimer m_pairingTimeout;
|
||||||
|
Device *m_device;
|
||||||
|
PairState m_pairState;
|
||||||
|
|
||||||
|
private Q_SLOTS:
|
||||||
|
void pairingTimeout();
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // KDECONNECT_PAIRINGHANDLER_H
|
#endif // KDECONNECT_PAIRINGHANDLER_H
|
||||||
|
|
|
@ -40,7 +40,6 @@ struct DaemonPrivate {
|
||||||
// Every known device
|
// Every known device
|
||||||
QMap<QString, Device *> m_devices;
|
QMap<QString, Device *> m_devices;
|
||||||
|
|
||||||
QSet<QString> m_discoveryModeAcquisitions;
|
|
||||||
bool m_testMode;
|
bool m_testMode;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -101,28 +100,6 @@ void Daemon::init()
|
||||||
qCDebug(KDECONNECT_CORE) << "Daemon started";
|
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)
|
void Daemon::removeDevice(Device *device)
|
||||||
{
|
{
|
||||||
d->m_devices.remove(device->id());
|
d->m_devices.remove(device->id());
|
||||||
|
@ -131,20 +108,6 @@ void Daemon::removeDevice(Device *device)
|
||||||
Q_EMIT deviceListChanged();
|
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()
|
void Daemon::forceOnNetworkChange()
|
||||||
{
|
{
|
||||||
|
@ -175,7 +138,7 @@ QStringList Daemon::devices(bool onlyReachable, bool onlyTrusted) const
|
||||||
for (Device *device : qAsConst(d->m_devices)) {
|
for (Device *device : qAsConst(d->m_devices)) {
|
||||||
if (onlyReachable && !device->isReachable())
|
if (onlyReachable && !device->isReachable())
|
||||||
continue;
|
continue;
|
||||||
if (onlyTrusted && !device->isTrusted())
|
if (onlyTrusted && !device->isPaired())
|
||||||
continue;
|
continue;
|
||||||
ret.append(device->id());
|
ret.append(device->id());
|
||||||
}
|
}
|
||||||
|
@ -188,7 +151,7 @@ QMap<QString, QString> Daemon::deviceNames(bool onlyReachable, bool onlyTrusted)
|
||||||
for (Device *device : qAsConst(d->m_devices)) {
|
for (Device *device : qAsConst(d->m_devices)) {
|
||||||
if (onlyReachable && !device->isReachable())
|
if (onlyReachable && !device->isReachable())
|
||||||
continue;
|
continue;
|
||||||
if (onlyTrusted && !device->isTrusted())
|
if (onlyTrusted && !device->isPaired())
|
||||||
continue;
|
continue;
|
||||||
ret[device->id()] = device->name();
|
ret[device->id()] = device->name();
|
||||||
}
|
}
|
||||||
|
@ -213,13 +176,7 @@ void Daemon::onNewDeviceLink(const NetworkPacket &identityPacket, DeviceLink *dl
|
||||||
} else {
|
} else {
|
||||||
qCDebug(KDECONNECT_CORE) << "It is a new device" << identityPacket.get<QString>(QStringLiteral("deviceName"));
|
qCDebug(KDECONNECT_CORE) << "It is a new device" << identityPacket.get<QString>(QStringLiteral("deviceName"));
|
||||||
Device *device = new Device(this, identityPacket, dl);
|
Device *device = new Device(this, identityPacket, dl);
|
||||||
|
addDevice(device);
|
||||||
// we discard the connections that we created but it's not paired.
|
|
||||||
if (!isDiscoveringDevices() && !device->isTrusted() && !dl->linkShouldBeKeptAlive()) {
|
|
||||||
device->deleteLater();
|
|
||||||
} else {
|
|
||||||
addDevice(device);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -229,7 +186,7 @@ void Daemon::onDeviceStatusChanged()
|
||||||
|
|
||||||
// qCDebug(KDECONNECT_CORE) << "Device" << device->name() << "status changed. Reachable:" << device->isReachable() << ". Paired: " << device->isPaired();
|
// 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();
|
// qCDebug(KDECONNECT_CORE) << "Destroying device" << device->name();
|
||||||
removeDevice(device);
|
removeDevice(device);
|
||||||
} else {
|
} else {
|
||||||
|
@ -284,15 +241,10 @@ QList<Device *> Daemon::devicesList() const
|
||||||
return d->m_devices.values();
|
return d->m_devices.values();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Daemon::isDiscoveringDevices() const
|
|
||||||
{
|
|
||||||
return !d->m_discoveryModeAcquisitions.isEmpty();
|
|
||||||
}
|
|
||||||
|
|
||||||
QString Daemon::deviceIdByName(const QString &name) const
|
QString Daemon::deviceIdByName(const QString &name) const
|
||||||
{
|
{
|
||||||
for (Device *device : qAsConst(d->m_devices)) {
|
for (Device *device : qAsConst(d->m_devices)) {
|
||||||
if (device->name() == name && device->isTrusted())
|
if (device->name() == name && device->isPaired())
|
||||||
return device->id();
|
return device->id();
|
||||||
}
|
}
|
||||||
return {};
|
return {};
|
||||||
|
@ -302,10 +254,11 @@ void Daemon::addDevice(Device *device)
|
||||||
{
|
{
|
||||||
const QString id = device->id();
|
const QString id = device->id();
|
||||||
connect(device, &Device::reachableChanged, this, &Daemon::onDeviceStatusChanged);
|
connect(device, &Device::reachableChanged, this, &Daemon::onDeviceStatusChanged);
|
||||||
connect(device, &Device::trustedChanged, this, &Daemon::onDeviceStatusChanged);
|
connect(device, &Device::pairStateChanged, this, &Daemon::onDeviceStatusChanged);
|
||||||
connect(device, &Device::hasPairingRequestsChanged, this, &Daemon::pairingRequestsChanged);
|
connect(device, &Device::pairStateChanged, this, &Daemon::pairingRequestsChanged);
|
||||||
connect(device, &Device::hasPairingRequestsChanged, this, [this, device](bool hasPairingRequests) {
|
connect(device, &Device::pairStateChanged, this, [this, device](int pairStateAsInt) {
|
||||||
if (hasPairingRequests)
|
PairState pairState = (PairState)pairStateAsInt;
|
||||||
|
if (pairState == PairState::RequestedByPeer)
|
||||||
askPairingConfirmation(device);
|
askPairingConfirmation(device);
|
||||||
});
|
});
|
||||||
d->m_devices[id] = device;
|
d->m_devices[id] = device;
|
||||||
|
@ -318,7 +271,7 @@ QStringList Daemon::pairingRequests() const
|
||||||
{
|
{
|
||||||
QStringList ret;
|
QStringList ret;
|
||||||
for (Device *dev : qAsConst(d->m_devices)) {
|
for (Device *dev : qAsConst(d->m_devices)) {
|
||||||
if (dev->hasPairingRequests())
|
if (dev->isPairRequestedByPeer())
|
||||||
ret += dev->id();
|
ret += dev->id();
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
|
|
|
@ -24,7 +24,6 @@ class KDECONNECTCORE_EXPORT Daemon : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
Q_CLASSINFO("D-Bus Interface", "org.kde.kdeconnect.daemon")
|
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 pairingRequests READ pairingRequests NOTIFY pairingRequestsChanged)
|
||||||
Q_PROPERTY(QStringList customDevices READ customDevices WRITE setCustomDevices NOTIFY customDevicesChanged)
|
Q_PROPERTY(QStringList customDevices READ customDevices WRITE setCustomDevices NOTIFY customDevicesChanged)
|
||||||
|
|
||||||
|
@ -54,9 +53,6 @@ public:
|
||||||
|
|
||||||
Q_SCRIPTABLE QString selfId() const;
|
Q_SCRIPTABLE QString selfId() const;
|
||||||
public Q_SLOTS:
|
public Q_SLOTS:
|
||||||
Q_SCRIPTABLE void acquireDiscoveryMode(const QString &id);
|
|
||||||
Q_SCRIPTABLE void releaseDiscoveryMode(const QString &id);
|
|
||||||
|
|
||||||
Q_SCRIPTABLE void forceOnNetworkChange();
|
Q_SCRIPTABLE void forceOnNetworkChange();
|
||||||
|
|
||||||
/// don't try to turn into Q_PROPERTY, it doesn't work
|
/// don't try to turn into Q_PROPERTY, it doesn't work
|
||||||
|
@ -90,9 +86,7 @@ private:
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void addDevice(Device *device);
|
void addDevice(Device *device);
|
||||||
bool isDiscoveringDevices() const;
|
|
||||||
void removeDevice(Device *d);
|
void removeDevice(Device *d);
|
||||||
void cleanDevices();
|
|
||||||
|
|
||||||
QScopedPointer<struct DaemonPrivate> d;
|
QScopedPointer<struct DaemonPrivate> d;
|
||||||
};
|
};
|
||||||
|
|
199
core/device.cpp
199
core/device.cpp
|
@ -39,6 +39,7 @@ public:
|
||||||
|
|
||||||
~DevicePrivate()
|
~DevicePrivate()
|
||||||
{
|
{
|
||||||
|
delete m_pairingHandler;
|
||||||
qDeleteAll(m_deviceLinks);
|
qDeleteAll(m_deviceLinks);
|
||||||
m_deviceLinks.clear();
|
m_deviceLinks.clear();
|
||||||
}
|
}
|
||||||
|
@ -54,7 +55,7 @@ public:
|
||||||
QMultiMap<QString, KdeConnectPlugin *> m_pluginsByIncomingCapability;
|
QMultiMap<QString, KdeConnectPlugin *> m_pluginsByIncomingCapability;
|
||||||
QSet<QString> m_supportedPlugins;
|
QSet<QString> m_supportedPlugins;
|
||||||
QSet<QString> m_allPlugins;
|
QSet<QString> m_allPlugins;
|
||||||
QSet<PairingHandler *> m_pairRequests;
|
PairingHandler* m_pairingHandler;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void warn(const QString &info)
|
static void warn(const QString &info)
|
||||||
|
@ -66,6 +67,8 @@ Device::Device(QObject *parent, const QString &id)
|
||||||
: QObject(parent)
|
: QObject(parent)
|
||||||
, d(new Device::DevicePrivate(id))
|
, d(new Device::DevicePrivate(id))
|
||||||
{
|
{
|
||||||
|
d->m_pairingHandler = new PairingHandler(this, PairState::Paired);
|
||||||
|
|
||||||
d->m_protocolVersion = NetworkPacket::s_protocolVersion;
|
d->m_protocolVersion = NetworkPacket::s_protocolVersion;
|
||||||
KdeConnectConfig::DeviceInfo info = KdeConnectConfig::instance().getTrustedDevice(d->m_deviceId);
|
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_allPlugins = PluginLoader::instance()->getPluginList().toSet();
|
||||||
d->m_supportedPlugins = d->m_allPlugins;
|
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)
|
Device::Device(QObject *parent, const NetworkPacket &identityPacket, DeviceLink *dl)
|
||||||
: QObject(parent)
|
: QObject(parent)
|
||||||
, d(new Device::DevicePrivate(identityPacket.get<QString>(QStringLiteral("deviceId"))))
|
, d(new Device::DevicePrivate(identityPacket.get<QString>(QStringLiteral("deviceId"))))
|
||||||
{
|
{
|
||||||
|
d->m_pairingHandler = new PairingHandler(this, PairState::NotPaired);
|
||||||
d->m_deviceName = identityPacket.get<QString>(QStringLiteral("deviceName"));
|
d->m_deviceName = identityPacket.get<QString>(QStringLiteral("deviceName"));
|
||||||
d->m_allPlugins = PluginLoader::instance()->getPluginList().toSet();
|
d->m_allPlugins = PluginLoader::instance()->getPluginList().toSet();
|
||||||
|
|
||||||
|
@ -94,10 +101,15 @@ Device::Device(QObject *parent, const NetworkPacket &identityPacket, DeviceLink
|
||||||
// Register in bus
|
// Register in bus
|
||||||
QDBusConnection::sessionBus().registerObject(dbusPath(), this, QDBusConnection::ExportScriptableContents | QDBusConnection::ExportAdaptors);
|
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::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()
|
Device::~Device()
|
||||||
|
@ -150,7 +162,7 @@ void Device::reloadPlugins()
|
||||||
QHash<QString, KdeConnectPlugin *> newPluginMap, oldPluginMap = d->m_plugins;
|
QHash<QString, KdeConnectPlugin *> newPluginMap, oldPluginMap = d->m_plugins;
|
||||||
QMultiMap<QString, KdeConnectPlugin *> newPluginsByIncomingCapability;
|
QMultiMap<QString, KdeConnectPlugin *> 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();
|
PluginLoader *loader = PluginLoader::instance();
|
||||||
|
|
||||||
|
@ -209,51 +221,60 @@ QString Device::pluginsConfigFile() const
|
||||||
return KdeConnectConfig::instance().deviceConfigDir(id()).absoluteFilePath(QStringLiteral("config"));
|
return KdeConnectConfig::instance().deviceConfigDir(id()).absoluteFilePath(QStringLiteral("config"));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Device::requestPair()
|
void Device::requestPairing()
|
||||||
{
|
{
|
||||||
if (isTrusted()) {
|
qCDebug(KDECONNECT_CORE) << "Request pairing";
|
||||||
Q_EMIT pairingError(i18n("Already paired"));
|
d->m_pairingHandler->requestPairing();
|
||||||
return;
|
Q_EMIT pairStateChanged(pairStateAsInt());
|
||||||
}
|
|
||||||
|
|
||||||
if (!isReachable()) {
|
|
||||||
Q_EMIT pairingError(i18n("Device not reachable"));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (DeviceLink *dl : qAsConst(d->m_deviceLinks)) {
|
|
||||||
dl->userRequestsPair();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Device::unpair()
|
void Device::unpair()
|
||||||
{
|
{
|
||||||
for (DeviceLink *dl : qAsConst(d->m_deviceLinks)) {
|
qCDebug(KDECONNECT_CORE) << "Request unpairing";
|
||||||
dl->userRequestsUnpair();
|
d->m_pairingHandler->unpair();
|
||||||
}
|
|
||||||
KdeConnectConfig::instance().removeTrustedDevice(id());
|
|
||||||
Q_EMIT trustedChanged(false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Device::pairStatusChanged(DeviceLink::PairStatus status)
|
void Device::acceptPairing()
|
||||||
{
|
{
|
||||||
if (status == DeviceLink::NotPaired) {
|
qCDebug(KDECONNECT_CORE) << "Accept pairing";
|
||||||
KdeConnectConfig::instance().removeTrustedDevice(id());
|
d->m_pairingHandler->acceptPairing();
|
||||||
|
}
|
||||||
|
|
||||||
for (DeviceLink *dl : qAsConst(d->m_deviceLinks)) {
|
void Device::cancelPairing()
|
||||||
if (dl != sender()) {
|
{
|
||||||
dl->setPairStatus(DeviceLink::NotPaired);
|
qCDebug(KDECONNECT_CORE) << "Cancel pairing";
|
||||||
}
|
d->m_pairingHandler->cancelPairing();
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
KdeConnectConfig::instance().addTrustedDevice(id(), name(), type());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
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
|
reloadPlugins(); // Will load/unload plugins
|
||||||
|
Q_EMIT pairStateChanged(pairStateAsInt());
|
||||||
|
}
|
||||||
|
|
||||||
bool isTrusted = (status == DeviceLink::Paired);
|
void Device::pairingHandler_pairingFailed(const QString &errorMessage)
|
||||||
Q_EMIT trustedChanged(isTrusted);
|
{
|
||||||
Q_ASSERT(isTrusted == this->isTrusted());
|
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)
|
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) {
|
if (d->m_deviceLinks.size() == 1) {
|
||||||
Q_EMIT reachableChanged(true);
|
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)
|
void Device::linkDestroyed(QObject *o)
|
||||||
|
@ -377,8 +348,7 @@ void Device::removeLink(DeviceLink *link)
|
||||||
|
|
||||||
bool Device::sendPacket(NetworkPacket &np)
|
bool Device::sendPacket(NetworkPacket &np)
|
||||||
{
|
{
|
||||||
Q_ASSERT(np.type() != PACKET_TYPE_PAIR);
|
Q_ASSERT(isPaired() || np.type() == PACKET_TYPE_PAIR);
|
||||||
Q_ASSERT(isTrusted());
|
|
||||||
|
|
||||||
// Maybe we could block here any packet that is not an identity or a pairing packet to prevent sending non encrypted data
|
// 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)) {
|
for (DeviceLink *dl : qAsConst(d->m_deviceLinks)) {
|
||||||
|
@ -391,8 +361,9 @@ bool Device::sendPacket(NetworkPacket &np)
|
||||||
|
|
||||||
void Device::privateReceivedPacket(const NetworkPacket &np)
|
void Device::privateReceivedPacket(const NetworkPacket &np)
|
||||||
{
|
{
|
||||||
Q_ASSERT(np.type() != PACKET_TYPE_PAIR);
|
if (np.type() == PACKET_TYPE_PAIR) {
|
||||||
if (isTrusted()) {
|
d->m_pairingHandler->packetReceived(np);
|
||||||
|
} else if (isPaired()) {
|
||||||
const QList<KdeConnectPlugin *> plugins = d->m_pluginsByIncomingCapability.values(np.type());
|
const QList<KdeConnectPlugin *> plugins = d->m_pluginsByIncomingCapability.values(np.type());
|
||||||
if (plugins.isEmpty()) {
|
if (plugins.isEmpty()) {
|
||||||
qWarning() << "discarding unsupported packet" << np.type() << "for" << name();
|
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 Device::availableLinks() const
|
||||||
{
|
{
|
||||||
QStringList sl;
|
QStringList sl;
|
||||||
|
@ -421,22 +414,6 @@ QStringList Device::availableLinks() const
|
||||||
return sl;
|
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
|
QHostAddress Device::getLocalIpAddress() const
|
||||||
{
|
{
|
||||||
for (DeviceLink *dl : qAsConst(d->m_deviceLinks)) {
|
for (DeviceLink *dl : qAsConst(d->m_deviceLinks)) {
|
||||||
|
@ -480,7 +457,7 @@ QString Device::type2str(Device::DeviceType deviceType)
|
||||||
|
|
||||||
QString Device::statusIconName() const
|
QString Device::statusIconName() const
|
||||||
{
|
{
|
||||||
return iconForStatus(isReachable(), isTrusted());
|
return iconForStatus(isReachable(), isPaired());
|
||||||
}
|
}
|
||||||
|
|
||||||
QString Device::iconName() const
|
QString Device::iconName() const
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
|
|
||||||
#include "backends/devicelink.h"
|
#include "backends/devicelink.h"
|
||||||
#include "networkpacket.h"
|
#include "networkpacket.h"
|
||||||
|
#include "pairstate.h"
|
||||||
|
|
||||||
class DeviceLink;
|
class DeviceLink;
|
||||||
class KdeConnectPlugin;
|
class KdeConnectPlugin;
|
||||||
|
@ -26,9 +27,11 @@ class KDECONNECTCORE_EXPORT Device : public QObject
|
||||||
Q_PROPERTY(QString iconName READ iconName CONSTANT)
|
Q_PROPERTY(QString iconName READ iconName CONSTANT)
|
||||||
Q_PROPERTY(QString statusIconName READ statusIconName NOTIFY statusIconNameChanged)
|
Q_PROPERTY(QString statusIconName READ statusIconName NOTIFY statusIconNameChanged)
|
||||||
Q_PROPERTY(bool isReachable READ isReachable NOTIFY reachableChanged)
|
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(QStringList supportedPlugins READ supportedPlugins NOTIFY pluginsChanged)
|
||||||
Q_PROPERTY(bool hasPairingRequests READ hasPairingRequests NOTIFY hasPairingRequestsChanged)
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
enum DeviceType {
|
enum DeviceType {
|
||||||
|
@ -72,7 +75,11 @@ public:
|
||||||
void addLink(const NetworkPacket &identityPacket, DeviceLink *);
|
void addLink(const NetworkPacket &identityPacket, DeviceLink *);
|
||||||
void removeLink(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;
|
Q_SCRIPTABLE QStringList availableLinks() const;
|
||||||
virtual bool isReachable() const;
|
virtual bool isReachable() const;
|
||||||
|
@ -86,8 +93,6 @@ public:
|
||||||
Q_SCRIPTABLE void setPluginEnabled(const QString &pluginName, bool enabled);
|
Q_SCRIPTABLE void setPluginEnabled(const QString &pluginName, bool enabled);
|
||||||
Q_SCRIPTABLE bool isPluginEnabled(const QString &pluginName) const;
|
Q_SCRIPTABLE bool isPluginEnabled(const QString &pluginName) const;
|
||||||
|
|
||||||
void cleanUnneededLinks();
|
|
||||||
|
|
||||||
int protocolVersion();
|
int protocolVersion();
|
||||||
QStringList supportedPlugins() const;
|
QStringList supportedPlugins() const;
|
||||||
|
|
||||||
|
@ -100,33 +105,32 @@ public Q_SLOTS:
|
||||||
|
|
||||||
// Dbus operations
|
// Dbus operations
|
||||||
public Q_SLOTS:
|
public Q_SLOTS:
|
||||||
Q_SCRIPTABLE void requestPair(); // to all links
|
Q_SCRIPTABLE void requestPairing();
|
||||||
Q_SCRIPTABLE void unpair(); // from all links
|
Q_SCRIPTABLE void unpair();
|
||||||
Q_SCRIPTABLE void reloadPlugins(); // from kconf
|
Q_SCRIPTABLE void reloadPlugins(); // from kconf
|
||||||
|
|
||||||
Q_SCRIPTABLE void acceptPairing();
|
Q_SCRIPTABLE void acceptPairing();
|
||||||
Q_SCRIPTABLE void rejectPairing();
|
Q_SCRIPTABLE void cancelPairing();
|
||||||
Q_SCRIPTABLE bool hasPairingRequests() const;
|
|
||||||
|
|
||||||
Q_SCRIPTABLE QString pluginIconName(const QString &pluginName);
|
Q_SCRIPTABLE QString pluginIconName(const QString &pluginName);
|
||||||
private Q_SLOTS:
|
private Q_SLOTS:
|
||||||
void privateReceivedPacket(const NetworkPacket &np);
|
void privateReceivedPacket(const NetworkPacket &np);
|
||||||
void linkDestroyed(QObject *o);
|
void linkDestroyed(QObject *o);
|
||||||
void pairStatusChanged(DeviceLink::PairStatus current);
|
|
||||||
void addPairingRequest(PairingHandler *handler);
|
void pairingHandler_incomingPairRequest();
|
||||||
void removePairingRequest(PairingHandler *handler);
|
void pairingHandler_pairingFailed(const QString &errorMessage);
|
||||||
|
void pairingHandler_pairingSuccessful();
|
||||||
|
void pairingHandler_unpaired();
|
||||||
|
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
Q_SCRIPTABLE void pluginsChanged();
|
Q_SCRIPTABLE void pluginsChanged();
|
||||||
Q_SCRIPTABLE void reachableChanged(bool reachable);
|
Q_SCRIPTABLE void reachableChanged(bool reachable);
|
||||||
Q_SCRIPTABLE void trustedChanged(bool trusted);
|
Q_SCRIPTABLE void pairStateChanged(int pairState); // Hack because qdbus doesn't like enums
|
||||||
Q_SCRIPTABLE void pairingError(const QString &error);
|
Q_SCRIPTABLE void pairingFailed(const QString &error);
|
||||||
Q_SCRIPTABLE void nameChanged(const QString &name);
|
Q_SCRIPTABLE void nameChanged(const QString &name);
|
||||||
Q_SCRIPTABLE void typeChanged(const QString &type);
|
Q_SCRIPTABLE void typeChanged(const QString &type);
|
||||||
Q_SCRIPTABLE void statusIconNameChanged();
|
Q_SCRIPTABLE void statusIconNameChanged();
|
||||||
|
|
||||||
Q_SCRIPTABLE void hasPairingRequestsChanged(bool hasPairingRequests);
|
|
||||||
|
|
||||||
private: // Methods
|
private: // Methods
|
||||||
static DeviceType str2type(const QString &deviceType);
|
static DeviceType str2type(const QString &deviceType);
|
||||||
static QString type2str(DeviceType deviceType);
|
static QString type2str(DeviceType deviceType);
|
||||||
|
|
18
core/pairstate.h
Normal file
18
core/pairstate.h
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
/**
|
||||||
|
* SPDX-FileCopyrightText: 2023 Albert Vaca <albertvaka@gmail.com>
|
||||||
|
*
|
||||||
|
* 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
|
|
@ -44,7 +44,7 @@ public:
|
||||||
void askPairingConfirmation(Device *device) override
|
void askPairingConfirmation(Device *device) override
|
||||||
{
|
{
|
||||||
KNotification *notification = new KNotification(QStringLiteral("pairingRequest"), KNotification::NotificationFlag::Persistent);
|
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->setIconName(QStringLiteral("dialog-information"));
|
||||||
notification->setComponentName(QStringLiteral("kdeconnect"));
|
notification->setComponentName(QStringLiteral("kdeconnect"));
|
||||||
notification->setTitle(QStringLiteral("KDE Connect"));
|
notification->setTitle(QStringLiteral("KDE Connect"));
|
||||||
|
@ -53,7 +53,7 @@ public:
|
||||||
notification->setDefaultAction(i18n("Open"));
|
notification->setDefaultAction(i18n("Open"));
|
||||||
notification->setActions(QStringList() << i18n("Accept") << i18n("Reject") << i18n("View key"));
|
notification->setActions(QStringList() << i18n("Accept") << i18n("Reject") << i18n("View key"));
|
||||||
connect(notification, &KNotification::action1Activated, device, &Device::acceptPairing);
|
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();
|
QString deviceId = device->id();
|
||||||
auto openSettings = [deviceId, notification] {
|
auto openSettings = [deviceId, notification] {
|
||||||
OpenConfig oc;
|
OpenConfig oc;
|
||||||
|
|
|
@ -105,7 +105,7 @@ int main(int argc, char **argv)
|
||||||
DeviceDbusInterface *dev = new DeviceDbusInterface(req, menu);
|
DeviceDbusInterface *dev = new DeviceDbusInterface(req, menu);
|
||||||
auto pairMenu = menu->addMenu(dev->name());
|
auto pairMenu = menu->addMenu(dev->name());
|
||||||
pairMenu->addAction(i18n("Pair"), dev, &DeviceDbusInterface::acceptPairing);
|
pairMenu->addAction(i18n("Pair"), dev, &DeviceDbusInterface::acceptPairing);
|
||||||
pairMenu->addAction(i18n("Reject"), dev, &DeviceDbusInterface::rejectPairing);
|
pairMenu->addAction(i18n("Reject"), dev, &DeviceDbusInterface::cancelPairing);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Add quit menu
|
// Add quit menu
|
||||||
|
|
|
@ -39,10 +39,9 @@ DeviceDbusInterface::DeviceDbusInterface(const QString &id, QObject *parent)
|
||||||
parent)
|
parent)
|
||||||
, m_id(id)
|
, 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::reachableChanged, this, &DeviceDbusInterface::reachableChangedProxy);
|
||||||
connect(this, &OrgKdeKdeconnectDeviceInterface::nameChanged, this, &DeviceDbusInterface::nameChangedProxy);
|
connect(this, &OrgKdeKdeconnectDeviceInterface::nameChanged, this, &DeviceDbusInterface::nameChangedProxy);
|
||||||
connect(this, &OrgKdeKdeconnectDeviceInterface::hasPairingRequestsChanged, this, &DeviceDbusInterface::hasPairingRequestsChangedProxy);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DeviceDbusInterface::~DeviceDbusInterface()
|
DeviceDbusInterface::~DeviceDbusInterface()
|
||||||
|
|
|
@ -56,9 +56,11 @@ class KDECONNECTINTERFACES_EXPORT DeviceDbusInterface : public OrgKdeKdeconnectD
|
||||||
// TODO: Workaround because OrgKdeKdeconnectDeviceInterface is not generating
|
// TODO: Workaround because OrgKdeKdeconnectDeviceInterface is not generating
|
||||||
// the signals for the properties
|
// the signals for the properties
|
||||||
Q_PROPERTY(bool isReachable READ isReachable NOTIFY reachableChangedProxy)
|
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(QString name READ name NOTIFY nameChangedProxy)
|
||||||
Q_PROPERTY(bool hasPairingRequests READ hasPairingRequests NOTIFY hasPairingRequestsChangedProxy)
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit DeviceDbusInterface(const QString &deviceId, QObject *parent = nullptr);
|
explicit DeviceDbusInterface(const QString &deviceId, QObject *parent = nullptr);
|
||||||
|
@ -69,9 +71,8 @@ public:
|
||||||
|
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
void nameChangedProxy(const QString &name);
|
void nameChangedProxy(const QString &name);
|
||||||
void trustedChangedProxy(bool paired);
|
void pairStateChangedProxy(int pairState);
|
||||||
void reachableChangedProxy(bool reachable);
|
void reachableChangedProxy(bool reachable);
|
||||||
void hasPairingRequestsChangedProxy(bool);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const QString m_id;
|
const QString m_id;
|
||||||
|
|
|
@ -43,7 +43,6 @@ DevicesModel::DevicesModel(QObject *parent)
|
||||||
connect(watcher, &QDBusServiceWatcher::serviceRegistered, this, &DevicesModel::refreshDeviceList);
|
connect(watcher, &QDBusServiceWatcher::serviceRegistered, this, &DevicesModel::refreshDeviceList);
|
||||||
connect(watcher, &QDBusServiceWatcher::serviceUnregistered, this, &DevicesModel::clearDevices);
|
connect(watcher, &QDBusServiceWatcher::serviceUnregistered, this, &DevicesModel::clearDevices);
|
||||||
|
|
||||||
// refresh the view, acquireDiscoveryMode if necessary
|
|
||||||
setDisplayFilter(NoFilter);
|
setDisplayFilter(NoFilter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -60,7 +59,6 @@ QHash<int, QByteArray> DevicesModel::roleNames() const
|
||||||
|
|
||||||
DevicesModel::~DevicesModel()
|
DevicesModel::~DevicesModel()
|
||||||
{
|
{
|
||||||
m_dbusInterface->releaseDiscoveryMode(*s_keyId);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int DevicesModel::rowForDevice(const QString &id) const
|
int DevicesModel::rowForDevice(const QString &id) const
|
||||||
|
@ -140,12 +138,6 @@ void DevicesModel::setDisplayFilter(int flags)
|
||||||
{
|
{
|
||||||
m_displayFilter = (StatusFilterFlag)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();
|
refreshDeviceList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -239,7 +231,7 @@ QVariant DevicesModel::data(const QModelIndex &index, int role) const
|
||||||
case NameModelRole:
|
case NameModelRole:
|
||||||
return device->name();
|
return device->name();
|
||||||
case Qt::ToolTipRole: {
|
case Qt::ToolTipRole: {
|
||||||
bool trusted = device->isTrusted();
|
bool trusted = device->isPaired();
|
||||||
bool reachable = device->isReachable();
|
bool reachable = device->isReachable();
|
||||||
QString status = reachable ? (trusted ? 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;
|
return status;
|
||||||
|
@ -249,7 +241,7 @@ QVariant DevicesModel::data(const QModelIndex &index, int role) const
|
||||||
if (device->isReachable()) {
|
if (device->isReachable()) {
|
||||||
status |= StatusFilterFlag::Reachable;
|
status |= StatusFilterFlag::Reachable;
|
||||||
}
|
}
|
||||||
if (device->isTrusted()) {
|
if (device->isPaired()) {
|
||||||
status |= StatusFilterFlag::Paired;
|
status |= StatusFilterFlag::Paired;
|
||||||
}
|
}
|
||||||
return status;
|
return status;
|
||||||
|
@ -287,5 +279,5 @@ bool DevicesModel::passesFilter(DeviceDbusInterface *dev) const
|
||||||
bool onlyPaired = (m_displayFilter & StatusFilterFlag::Paired);
|
bool onlyPaired = (m_displayFilter & StatusFilterFlag::Paired);
|
||||||
bool onlyReachable = (m_displayFilter & StatusFilterFlag::Reachable);
|
bool onlyReachable = (m_displayFilter & StatusFilterFlag::Reachable);
|
||||||
|
|
||||||
return !((onlyReachable && !dev->isReachable()) || (onlyPaired && !dev->isTrusted()));
|
return !((onlyReachable && !dev->isReachable()) || (onlyPaired && !dev->isPaired()));
|
||||||
}
|
}
|
||||||
|
|
87
kcm/kcm.cpp
87
kcm/kcm.cpp
|
@ -84,8 +84,9 @@ KdeConnectKcm::KdeConnectKcm(QWidget *parent, const QVariantList &args)
|
||||||
connect(devicesModel, &QAbstractItemModel::dataChanged, this, &KdeConnectKcm::resetSelection);
|
connect(devicesModel, &QAbstractItemModel::dataChanged, this, &KdeConnectKcm::resetSelection);
|
||||||
connect(kcmUi->deviceList->selectionModel(), &QItemSelectionModel::currentChanged, this, &KdeConnectKcm::deviceSelected);
|
connect(kcmUi->deviceList->selectionModel(), &QItemSelectionModel::currentChanged, this, &KdeConnectKcm::deviceSelected);
|
||||||
connect(kcmUi->accept_button, &QAbstractButton::clicked, this, &KdeConnectKcm::acceptPairing);
|
connect(kcmUi->accept_button, &QAbstractButton::clicked, this, &KdeConnectKcm::acceptPairing);
|
||||||
connect(kcmUi->reject_button, &QAbstractButton::clicked, this, &KdeConnectKcm::rejectPairing);
|
connect(kcmUi->reject_button, &QAbstractButton::clicked, this, &KdeConnectKcm::cancelPairing);
|
||||||
connect(kcmUi->pair_button, &QAbstractButton::clicked, this, &KdeConnectKcm::requestPair);
|
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->unpair_button, &QAbstractButton::clicked, this, &KdeConnectKcm::unpair);
|
||||||
connect(kcmUi->ping_button, &QAbstractButton::clicked, this, &KdeConnectKcm::sendPing);
|
connect(kcmUi->ping_button, &QAbstractButton::clicked, this, &KdeConnectKcm::sendPing);
|
||||||
connect(kcmUi->refresh_button, &QAbstractButton::clicked, this, &KdeConnectKcm::refresh);
|
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->renameDone_button, &QAbstractButton::clicked, this, &KdeConnectKcm::renameDone);
|
||||||
connect(kcmUi->renameShow_button, &QAbstractButton::clicked, this, &KdeConnectKcm::renameShow);
|
connect(kcmUi->renameShow_button, &QAbstractButton::clicked, this, &KdeConnectKcm::renameShow);
|
||||||
|
|
||||||
daemon->acquireDiscoveryMode(createId());
|
|
||||||
|
|
||||||
#if KCMUTILS_VERSION >= QT_VERSION_CHECK(5, 45, 0)
|
#if KCMUTILS_VERSION >= QT_VERSION_CHECK(5, 45, 0)
|
||||||
|
|
||||||
if (!args.isEmpty() && args.first().type() == QVariant::String) {
|
if (!args.isEmpty() && args.first().type() == QVariant::String) {
|
||||||
|
@ -147,13 +146,11 @@ void KdeConnectKcm::setRenameMode(bool b)
|
||||||
|
|
||||||
KdeConnectKcm::~KdeConnectKcm()
|
KdeConnectKcm::~KdeConnectKcm()
|
||||||
{
|
{
|
||||||
daemon->releaseDiscoveryMode(createId());
|
|
||||||
delete kcmUi;
|
delete kcmUi;
|
||||||
}
|
}
|
||||||
|
|
||||||
void KdeConnectKcm::refresh()
|
void KdeConnectKcm::refresh()
|
||||||
{
|
{
|
||||||
daemon->acquireDiscoveryMode(createId());
|
|
||||||
daemon->forceOnNetworkChange();
|
daemon->forceOnNetworkChange();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -191,23 +188,8 @@ void KdeConnectKcm::deviceSelected(const QModelIndex ¤t)
|
||||||
resetDeviceView();
|
resetDeviceView();
|
||||||
|
|
||||||
connect(currentDevice, SIGNAL(pluginsChanged()), this, SLOT(resetCurrentDevice()));
|
connect(currentDevice, SIGNAL(pluginsChanged()), this, SLOT(resetCurrentDevice()));
|
||||||
connect(currentDevice, SIGNAL(trustedChanged(bool)), this, SLOT(trustedChanged(bool)));
|
connect(currentDevice, SIGNAL(pairingFailed(QString)), this, SLOT(pairingFailed(QString)));
|
||||||
connect(currentDevice, SIGNAL(pairingError(QString)), this, SLOT(pairingFailed(QString)));
|
connect(currentDevice, &DeviceDbusInterface::pairStateChangedProxy, this, &KdeConnectKcm::setCurrentDevicePairState);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void KdeConnectKcm::resetCurrentDevice()
|
void KdeConnectKcm::resetCurrentDevice()
|
||||||
|
@ -225,17 +207,9 @@ void KdeConnectKcm::resetDeviceView()
|
||||||
|
|
||||||
kcmUi->name_label->setText(currentDevice->name());
|
kcmUi->name_label->setText(currentDevice->name());
|
||||||
setWhenAvailable(
|
setWhenAvailable(
|
||||||
currentDevice->isTrusted(),
|
currentDevice->pairStateAsInt(),
|
||||||
[this](bool trusted) {
|
[this](int pairStateAsInt) {
|
||||||
if (trusted)
|
setCurrentDevicePairState(pairStateAsInt);
|
||||||
setCurrentDeviceTrusted(Trusted);
|
|
||||||
else
|
|
||||||
setWhenAvailable(
|
|
||||||
currentDevice->hasPairingRequests(),
|
|
||||||
[this](bool haspr) {
|
|
||||||
setCurrentDeviceTrusted(haspr ? RequestedByPeer : NotTrusted);
|
|
||||||
},
|
|
||||||
this);
|
|
||||||
},
|
},
|
||||||
this);
|
this);
|
||||||
|
|
||||||
|
@ -257,7 +231,7 @@ void KdeConnectKcm::resetDeviceView()
|
||||||
connect(kcmUi->pluginSelector, &KPluginWidget::changed, this, &KdeConnectKcm::pluginsConfigChanged);
|
connect(kcmUi->pluginSelector, &KPluginWidget::changed, this, &KdeConnectKcm::pluginsConfigChanged);
|
||||||
}
|
}
|
||||||
|
|
||||||
void KdeConnectKcm::requestPair()
|
void KdeConnectKcm::requestPairing()
|
||||||
{
|
{
|
||||||
if (!currentDevice) {
|
if (!currentDevice) {
|
||||||
return;
|
return;
|
||||||
|
@ -265,9 +239,7 @@ void KdeConnectKcm::requestPair()
|
||||||
|
|
||||||
kcmUi->messages->hide();
|
kcmUi->messages->hide();
|
||||||
|
|
||||||
setCurrentDeviceTrusted(Requested);
|
currentDevice->requestPairing();
|
||||||
|
|
||||||
currentDevice->requestPair();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void KdeConnectKcm::unpair()
|
void KdeConnectKcm::unpair()
|
||||||
|
@ -276,7 +248,6 @@ void KdeConnectKcm::unpair()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
setCurrentDeviceTrusted(NotTrusted);
|
|
||||||
currentDevice->unpair();
|
currentDevice->unpair();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -289,13 +260,13 @@ void KdeConnectKcm::acceptPairing()
|
||||||
currentDevice->acceptPairing();
|
currentDevice->acceptPairing();
|
||||||
}
|
}
|
||||||
|
|
||||||
void KdeConnectKcm::rejectPairing()
|
void KdeConnectKcm::cancelPairing()
|
||||||
{
|
{
|
||||||
if (!currentDevice) {
|
if (!currentDevice) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
currentDevice->rejectPairing();
|
currentDevice->cancelPairing();
|
||||||
}
|
}
|
||||||
|
|
||||||
void KdeConnectKcm::pairingFailed(const QString &error)
|
void KdeConnectKcm::pairingFailed(const QString &error)
|
||||||
|
@ -303,38 +274,32 @@ void KdeConnectKcm::pairingFailed(const QString &error)
|
||||||
if (sender() != currentDevice)
|
if (sender() != currentDevice)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
setCurrentDeviceTrusted(NotTrusted);
|
|
||||||
|
|
||||||
kcmUi->messages->setText(i18n("Error trying to pair: %1", error));
|
kcmUi->messages->setText(i18n("Error trying to pair: %1", error));
|
||||||
kcmUi->messages->animatedShow();
|
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);
|
PairState state = (PairState)pairStateAsInt; // Hack because qdbus doesn't like enums
|
||||||
kcmUi->reject_button->setVisible(trusted == RequestedByPeer);
|
kcmUi->accept_button->setVisible(state == PairState::RequestedByPeer);
|
||||||
kcmUi->pair_button->setVisible(trusted == NotTrusted);
|
kcmUi->reject_button->setVisible(state == PairState::RequestedByPeer);
|
||||||
kcmUi->unpair_button->setVisible(trusted == Trusted);
|
kcmUi->cancel_button->setVisible(state == PairState::Requested);
|
||||||
kcmUi->progressBar->setVisible(trusted == Requested);
|
kcmUi->pair_button->setVisible(state == PairState::NotPaired);
|
||||||
kcmUi->ping_button->setVisible(trusted == Trusted);
|
kcmUi->unpair_button->setVisible(state == PairState::Paired);
|
||||||
switch (trusted) {
|
kcmUi->progressBar->setVisible(state == PairState::Requested);
|
||||||
case Trusted:
|
kcmUi->ping_button->setVisible(state == PairState::Paired);
|
||||||
|
switch (state) {
|
||||||
|
case PairState::Paired:
|
||||||
kcmUi->status_label->setText(i18n("(paired)"));
|
kcmUi->status_label->setText(i18n("(paired)"));
|
||||||
break;
|
break;
|
||||||
case NotTrusted:
|
case PairState::NotPaired:
|
||||||
kcmUi->status_label->setText(i18n("(not paired)"));
|
kcmUi->status_label->setText(i18n("(not paired)"));
|
||||||
break;
|
break;
|
||||||
case RequestedByPeer:
|
case PairState::RequestedByPeer:
|
||||||
kcmUi->status_label->setText(i18n("(incoming pair request)"));
|
kcmUi->status_label->setText(i18n("(incoming pair request)"));
|
||||||
break;
|
break;
|
||||||
case Requested:
|
case PairState::Requested:
|
||||||
kcmUi->status_label->setText(i18n("(pairing requested)"));
|
kcmUi->status_label->setText(i18n("(pairing requested)"));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
12
kcm/kcm.h
12
kcm/kcm.h
|
@ -10,6 +10,8 @@
|
||||||
#include <KCModule>
|
#include <KCModule>
|
||||||
#include <QStandardItemModel>
|
#include <QStandardItemModel>
|
||||||
|
|
||||||
|
#include <core/pairstate.h>
|
||||||
|
|
||||||
class QModelIndex;
|
class QModelIndex;
|
||||||
class DeviceDbusInterface;
|
class DeviceDbusInterface;
|
||||||
class DaemonDbusInterface;
|
class DaemonDbusInterface;
|
||||||
|
@ -35,24 +37,22 @@ private:
|
||||||
|
|
||||||
private Q_SLOTS:
|
private Q_SLOTS:
|
||||||
void deviceSelected(const QModelIndex ¤t);
|
void deviceSelected(const QModelIndex ¤t);
|
||||||
void requestPair();
|
void requestPairing();
|
||||||
void pluginsConfigChanged();
|
void pluginsConfigChanged();
|
||||||
void sendPing();
|
void sendPing();
|
||||||
void resetSelection();
|
void resetSelection();
|
||||||
void trustedChanged(bool);
|
|
||||||
void pairingFailed(const QString &error);
|
void pairingFailed(const QString &error);
|
||||||
void refresh();
|
void refresh();
|
||||||
void renameShow();
|
void renameShow();
|
||||||
void renameDone();
|
void renameDone();
|
||||||
void setRenameMode(bool b);
|
void setRenameMode(bool b);
|
||||||
void resetCurrentDevice();
|
void resetCurrentDevice();
|
||||||
void currentDevicePairingChanged(bool pairing);
|
void setCurrentDevicePairState(int pairStateAsInt);
|
||||||
void acceptPairing();
|
void acceptPairing();
|
||||||
void rejectPairing();
|
void cancelPairing();
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
enum TrustStatus { NotTrusted, Requested, RequestedByPeer, Trusted };
|
|
||||||
void setCurrentDeviceTrusted(TrustStatus trusted);
|
|
||||||
void resetDeviceView();
|
void resetDeviceView();
|
||||||
|
|
||||||
Ui::KdeConnectKcmUi *kcmUi;
|
Ui::KdeConnectKcmUi *kcmUi;
|
||||||
|
|
13
kcm/kcm.ui
13
kcm/kcm.ui
|
@ -251,6 +251,19 @@
|
||||||
</property>
|
</property>
|
||||||
</spacer>
|
</spacer>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="cancel_button">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Cancel</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QProgressBar" name="progressBar">
|
<widget class="QProgressBar" name="progressBar">
|
||||||
<property name="sizePolicy">
|
<property name="sizePolicy">
|
||||||
|
|
|
@ -137,7 +137,7 @@ KIO::WorkerResult KioKdeconnect::listDevice(const QString &device)
|
||||||
|
|
||||||
DeviceDbusInterface dev(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()));
|
return KIO::WorkerResult::fail(KIO::ERR_WORKER_DEFINED, i18n("%0 is not paired").arg(dev.name()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -36,12 +36,11 @@ private Q_SLOTS:
|
||||||
}
|
}
|
||||||
|
|
||||||
Device *d = nullptr;
|
Device *d = nullptr;
|
||||||
m_daemon->acquireDiscoveryMode(QStringLiteral("plugintest"));
|
|
||||||
const QList<Device *> devicesList = m_daemon->devicesList();
|
const QList<Device *> devicesList = m_daemon->devicesList();
|
||||||
for (Device *id : devicesList) {
|
for (Device *id : devicesList) {
|
||||||
if (id->isReachable()) {
|
if (id->isReachable()) {
|
||||||
if (!id->isTrusted())
|
if (!id->isPaired())
|
||||||
id->requestPair();
|
id->requestPairing();
|
||||||
d = id;
|
d = id;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -49,14 +48,13 @@ private Q_SLOTS:
|
||||||
if (d == nullptr) {
|
if (d == nullptr) {
|
||||||
QFAIL("Unable to determine device");
|
QFAIL("Unable to determine device");
|
||||||
}
|
}
|
||||||
m_daemon->releaseDiscoveryMode(QStringLiteral("plugintest"));
|
|
||||||
|
|
||||||
if (!d->loadedPlugins().contains(QStringLiteral("kdeconnect_remotecontrol"))) {
|
if (!d->loadedPlugins().contains(QStringLiteral("kdeconnect_remotecontrol"))) {
|
||||||
QSKIP("kdeconnect_remotecontrol is required for this test");
|
QSKIP("kdeconnect_remotecontrol is required for this test");
|
||||||
}
|
}
|
||||||
|
|
||||||
QVERIFY(d);
|
QVERIFY(d);
|
||||||
QVERIFY(d->isTrusted());
|
QVERIFY(d->isPaired());
|
||||||
QVERIFY(d->isReachable());
|
QVERIFY(d->isReachable());
|
||||||
|
|
||||||
d->setPluginEnabled(QStringLiteral("kdeconnect_mousepad"), false);
|
d->setPluginEnabled(QStringLiteral("kdeconnect_mousepad"), false);
|
||||||
|
|
|
@ -40,22 +40,20 @@ private Q_SLOTS:
|
||||||
QFAIL("No links available, but loopback should have been provided by the test");
|
QFAIL("No links available, but loopback should have been provided by the test");
|
||||||
}
|
}
|
||||||
|
|
||||||
m_daemon->acquireDiscoveryMode(QStringLiteral("test"));
|
|
||||||
Device *d = nullptr;
|
Device *d = nullptr;
|
||||||
const QList<Device *> devicesList = m_daemon->devicesList();
|
const QList<Device *> devicesList = m_daemon->devicesList();
|
||||||
for (Device *id : devicesList) {
|
for (Device *id : devicesList) {
|
||||||
if (id->isReachable()) {
|
if (id->isReachable()) {
|
||||||
if (!id->isTrusted())
|
if (!id->isPaired())
|
||||||
id->requestPair();
|
id->requestPairing();
|
||||||
d = id;
|
d = id;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (d == nullptr) {
|
if (d == nullptr) {
|
||||||
QFAIL("Unable to determine device");
|
QFAIL("Unable to determine device");
|
||||||
}
|
}
|
||||||
m_daemon->releaseDiscoveryMode(QStringLiteral("test"));
|
|
||||||
QCOMPARE(d->isReachable(), true);
|
QCOMPARE(d->isReachable(), true);
|
||||||
QCOMPARE(d->isTrusted(), true);
|
QCOMPARE(d->isPaired(), true);
|
||||||
|
|
||||||
QByteArray content("12312312312313213123213123");
|
QByteArray content("12312312312313213123213123");
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue