[OpenDocString] kdeconnect-kde (cpp)
daemon.cpp
Daemon *Daemon::instance()
{
    Q_ASSERT(s_instance != nullptr);
    return s_instance;
}
This returns the singleton object of the class Daemon.
Daemon::Daemon(QObject *parent, bool testMode)
    : QObject(parent)
    , d(new DaemonPrivate)
{
    Q_ASSERT(!s_instance);
    s_instance = this;
    d->m_testMode = testMode;

    // HACK init may call pure virtual functions from this class so it can't be called directly from the ctor
    QTimer::singleShot(0, this, &Daemon::init);
}
This constructor builds a daemon object and its d-pointer. It takes the parent object, sets test mode and calls the init method using a QTimer.
void Daemon::init()
{
    qCDebug(KDECONNECT_CORE) << "Daemon starting";

    // Load backends
    if (d->m_testMode)
        d->m_linkProviders.insert(new LoopbackLinkProvider());
    else {
        d->m_linkProviders.insert(new LanLinkProvider());
#ifdef KDECONNECT_BLUETOOTH
        d->m_linkProviders.insert(new BluetoothLinkProvider());
#endif
#ifdef KDECONNECT_LOOPBACK
        d->m_linkProviders.insert(new LoopbackLinkProvider());
#endif
    }

    // Register on DBus
    qDBusRegisterMetaType>();
    QDBusConnection::sessionBus().registerService(QStringLiteral("org.kde.kdeconnect"));
    QDBusConnection::sessionBus().registerObject(QStringLiteral("/modules/kdeconnect"), this, QDBusConnection::ExportScriptableContents);

    // Read remembered paired devices
    const QStringList &list = KdeConnectConfig::instance().trustedDevices();
    for (const QString &id : list) {
        addDevice(new Device(this, id));
    }

    // Listen to new devices
    for (LinkProvider *a : qAsConst(d->m_linkProviders)) {
        connect(a, &LinkProvider::onConnectionReceived, this, &Daemon::onNewDeviceLink);
        a->onStart();
    }

    NotificationServerInfo::instance().init();

    qCDebug(KDECONNECT_CORE) << "Daemon started";
}
This registers on DBus and connects to new devices. It also connects to new devices using the link providers.
void Daemon::acquireDiscoveryMode(const QString &key)
{
    bool oldState = d->m_discoveryModeAcquisitions.isEmpty();

    d->m_discoveryModeAcquisitions.insert(key);

    if (oldState != d->m_discoveryModeAcquisitions.isEmpty()) {
        forceOnNetworkChange();
    }
}
This adds a key to the list of keys that require discovery. It forces a network change if the list has changed.
void Daemon::releaseDiscoveryMode(const QString &key)
{
    bool oldState = d->m_discoveryModeAcquisitions.isEmpty();

    d->m_discoveryModeAcquisitions.remove(key);

    if (oldState != d->m_discoveryModeAcquisitions.isEmpty()) {
        cleanDevices();
    }
}
This removes the discovery mode entry of the given key, and cleans the devices if the list wasn't empty.
void Daemon::removeDevice(Device *device)
{
    d->m_devices.remove(device->id());
    device->deleteLater();
    Q_EMIT deviceRemoved(device->id());
    Q_EMIT deviceListChanged();
}
This removes the device object from the internal list of devices, and marks it for deletion. Signals deviceRemoved and deviceListChanged are emitted.
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);
        }
    }
}
This cleans unneeded links from not trusted devices, and removes the devices that are not reachable.
void Daemon::forceOnNetworkChange()
{
    qCDebug(KDECONNECT_CORE) << "Sending onNetworkChange to" << d->m_linkProviders.size() << "LinkProviders";
    for (LinkProvider *a : qAsConst(d->m_linkProviders)) {
        a->onNetworkChange();
    }
}
This sends a onNetworkChange signal on each link provider.
Device *Daemon::getDevice(const QString &deviceId)
{
    for (Device *device : qAsConst(d->m_devices)) {
        if (device->id() == deviceId) {
            return device;
        }
    }
    return nullptr;
}
Returns a pointer to the device object of the given deviceId.
const QSet &Daemon::getLinkProviders() const
{
    return d->m_linkProviders;
}
Returns a copy of the link providers list, which uses implicit sharing for its internal state.
QStringList Daemon::devices(bool onlyReachable, bool onlyTrusted) const
{
    QStringList ret;
    for (Device *device : qAsConst(d->m_devices)) {
        if (onlyReachable && !device->isReachable())
            continue;
        if (onlyTrusted && !device->isTrusted())
            continue;
        ret.append(device->id());
    }
    return ret;
}
Returns a list of all devices, optionally filtered by reachable and trusted.
QMap Daemon::deviceNames(bool onlyReachable, bool onlyTrusted) const
{
    QMap ret;
    for (Device *device : qAsConst(d->m_devices)) {
        if (onlyReachable && !device->isReachable())
            continue;
        if (onlyTrusted && !device->isTrusted())
            continue;
        ret[device->id()] = device->name();
    }
    return ret;
}
This code creates a map of device ids and names. It allows to filter out reachable and trusted devices.
void Daemon::onNewDeviceLink(const NetworkPacket &identityPacket, DeviceLink *dl)
{
    const QString &id = identityPacket.get(QStringLiteral("deviceId"));

    // qCDebug(KDECONNECT_CORE) << "Device discovered" << id << "via" << dl->provider()->name();

    if (d->m_devices.contains(id)) {
        qCDebug(KDECONNECT_CORE) << "It is a known device" << identityPacket.get(QStringLiteral("deviceName"));
        Device *device = d->m_devices[id];
        bool wasReachable = device->isReachable();
        device->addLink(identityPacket, dl);
        if (!wasReachable) {
            Q_EMIT deviceVisibilityChanged(id, true);
            Q_EMIT deviceListChanged();
        }
    } else {
        qCDebug(KDECONNECT_CORE) << "It is a new device" << identityPacket.get(QStringLiteral("deviceName"));
        Device *device = new Device(this, identityPacket, dl);

        // we discard the connections that we created but it's not paired.
        if (!isDiscoveringDevices() && !device->isTrusted() && !dl->linkShouldBeKeptAlive()) {
            device->deleteLater();
        } else {
            addDevice(device);
        }
    }
}
This adds a DeviceLink object to the device list of the internal list of devices. It checks if the device is known and if it is reachable, it adds the packet to the device list, and emits signals if the device is not reachable.
void Daemon::onDeviceStatusChanged()
{
    Device *device = (Device *)sender();

    // qCDebug(KDECONNECT_CORE) << "Device" << device->name() << "status changed. Reachable:" << device->isReachable() << ". Paired: " << device->isPaired();

    if (!device->isReachable() && !device->isTrusted()) {
        // qCDebug(KDECONNECT_CORE) << "Destroying device" << device->name();
        removeDevice(device);
    } else {
        Q_EMIT deviceVisibilityChanged(device->id(), device->isReachable());
        Q_EMIT deviceListChanged();
    }
}
This removes the device that sent the signal if it is not reachable and trusted from the list of connected devices. Otherwise it emits signals to tell that the devices visibility and the list of connected devices have changed.
void Daemon::setAnnouncedName(const QString &name)
{
    qCDebug(KDECONNECT_CORE) << "Announcing name";
    KdeConnectConfig::instance().setName(name);
    forceOnNetworkChange();
    Q_EMIT announcedNameChanged(name);
}
Sets the name of the daemon to the internal configuration object, and forces a network change.
void Daemon::setCustomDevices(const QStringList &addresses)
{
    auto &config = KdeConnectConfig::instance();

    auto customDevices = config.customDevices();
    if (customDevices != addresses) {
        qCDebug(KDECONNECT_CORE) << "Changed list of custom device addresses:" << addresses;
        config.setCustomDevices(addresses);
        Q_EMIT customDevicesChanged(addresses);

        forceOnNetworkChange();
    }
}
Sets addresses of custom devices to the internal list of addresses, and emits a signal onNetworkChange.
QStringList Daemon::customDevices() const
{
    return KdeConnectConfig::instance().customDevices();
}
Returns the list of custom devices stored in the internal configuration list.
QString Daemon::announcedName()
{
    return KdeConnectConfig::instance().name();
}
Returns the name stored in the KdeConnectConfig singleton instance.
QNetworkAccessManager *Daemon::networkAccessManager()
{
    static QPointer manager;
    if (!manager) {
        manager = new QNetworkAccessManager(this);
    }
    return manager;
}
This returns a pointer to a static instance of the network access manager.
QList Daemon::devicesList() const
{
    return d->m_devices.values();
}
Returns a list of all devices.
bool Daemon::isDiscoveringDevices() const
{
    return !d->m_discoveryModeAcquisitions.isEmpty();
}
This implements checking if the devices are discovered. It is only checked if the list of acquisitions is not empty.
QString Daemon::deviceIdByName(const QString &name) const
{
    for (Device *device : qAsConst(d->m_devices)) {
        if (device->name() == name && device->isTrusted())
            return device->id();
    }
    return {};
}
Returns the id of the first device with the given name.
void Daemon::addDevice(Device *device)
{
    const QString id = device->id();
    connect(device, &Device::reachableChanged, this, &Daemon::onDeviceStatusChanged);
    connect(device, &Device::trustedChanged, this, &Daemon::onDeviceStatusChanged);
    connect(device, &Device::hasPairingRequestsChanged, this, &Daemon::pairingRequestsChanged);
    connect(device, &Device::hasPairingRequestsChanged, this, [this, device](bool hasPairingRequests) {
        if (hasPairingRequests)
            askPairingConfirmation(device);
    });
    d->m_devices[id] = device;

    Q_EMIT deviceAdded(id);
    Q_EMIT deviceListChanged();
}
This adds a device object to the internal list of devices, and sets up signal/slot connections for reachable and trusted change events. It asks the pairing confirmation if the device has pairing requests.
QStringList Daemon::pairingRequests() const
{
    QStringList ret;
    for (Device *dev : qAsConst(d->m_devices)) {
        if (dev->hasPairingRequests())
            ret += dev->id();
    }
    return ret;
}
Returns a list of all ids of devices that have pairing requests.
Daemon::~Daemon()
{
}
This class is used to shutdown the application.
QString Daemon::selfId() const
{
    return KdeConnectConfig::instance().deviceId();
}
Returns the id of the current device.