From 30262da8a5fa7669360e4a57a321ae7c63b521db Mon Sep 17 00:00:00 2001 From: Devin Lin Date: Thu, 14 Dec 2023 21:15:39 -0800 Subject: [PATCH] kcms/cellularnetwork: Port to qcoro to make it async Fixes https://invent.kde.org/plasma/plasma-mobile/-/issues/284 --- CMakeLists.txt | 3 + kcms/cellularnetwork/CMakeLists.txt | 1 + kcms/cellularnetwork/modem.cpp | 112 +++++++++++++--------------- kcms/cellularnetwork/modem.h | 14 ++-- kcms/cellularnetwork/sim.cpp | 108 +++++++++++++++------------ kcms/cellularnetwork/sim.h | 10 ++- kcms/cellularnetwork/ui/main.qml | 2 +- 7 files changed, 130 insertions(+), 120 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index ec5d5ab0..ac308f27 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -77,6 +77,9 @@ find_package(KWayland CONFIG REQUIRED) find_package(PkgConfig REQUIRED) +find_package(QCoro6 REQUIRED COMPONENTS DBus) +qcoro_enable_coroutines() + pkg_check_modules(GOBJECT gobject-2.0 REQUIRED IMPORTED_TARGET) pkg_check_modules(GIO gio-2.0 REQUIRED IMPORTED_TARGET) diff --git a/kcms/cellularnetwork/CMakeLists.txt b/kcms/cellularnetwork/CMakeLists.txt index 48d2e146..846bb421 100644 --- a/kcms/cellularnetwork/CMakeLists.txt +++ b/kcms/cellularnetwork/CMakeLists.txt @@ -22,4 +22,5 @@ target_link_libraries(kcm_cellular_network PRIVATE KF6::NetworkManagerQt KF6::ModemManagerQt KF6::KCMUtilsQuick + QCoro::DBus ) diff --git a/kcms/cellularnetwork/modem.cpp b/kcms/cellularnetwork/modem.cpp index 2179a435..81c22c8c 100644 --- a/kcms/cellularnetwork/modem.cpp +++ b/kcms/cellularnetwork/modem.cpp @@ -7,6 +7,9 @@ #include #include +#include + +#include Modem::Modem(QObject *parent) : QObject{parent} @@ -116,12 +119,13 @@ QString Modem::activeConnectionUni() const return QString(); } -void Modem::reset() +QCoro::Task Modem::reset() { qDebug() << QStringLiteral("Resetting the modem..."); - QDBusPendingReply reply = m_mmInterface->reset(); - reply.waitForFinished(); - if (reply.isError()) { + + QDBusReply reply = co_await m_mmInterface->reset(); + + if (reply.isValid()) { qDebug() << QStringLiteral("Error resetting the modem:") << reply.error().message(); CellularNetworkSettings::instance()->addMessage(InlineMessage::Error, i18n("Error resetting the modem: %1", reply.error().message())); } @@ -207,51 +211,43 @@ void Modem::setMobileDataEnabled(bool enabled) bool Modem::isRoaming() const { - if (!m_nmModem) { + if (!m_nmModem || !m_nmModem->activeConnection() || !m_nmModem->activeConnection()->connection()) { return false; } - if (m_nmModem->activeConnection() && m_nmModem->activeConnection()->connection()) { - auto connection = m_nmModem->activeConnection()->connection(); - NetworkManager::GsmSetting::Ptr gsmSetting = connection->settings()->setting(NetworkManager::Setting::Gsm).dynamicCast(); - if (gsmSetting) { - return !gsmSetting->homeOnly(); - } - } + auto connection = m_nmModem->activeConnection()->connection(); + NetworkManager::GsmSetting::Ptr gsmSetting = connection->settings()->setting(NetworkManager::Setting::Gsm).dynamicCast(); - return false; + return gsmSetting ? !gsmSetting->homeOnly() : false; } -void Modem::setIsRoaming(bool roaming) +QCoro::Task Modem::setIsRoaming(bool roaming) { - if (!m_nmModem) { - return; + if (!m_nmModem || !m_nmModem->activeConnection() || !m_nmModem->activeConnection()->connection()) { + co_return; } - if (m_nmModem->activeConnection() && m_nmModem->activeConnection()->connection()) { - auto connection = m_nmModem->activeConnection()->connection(); + auto connection = m_nmModem->activeConnection()->connection(); - NetworkManager::GsmSetting::Ptr gsmSetting = connection->settings()->setting(NetworkManager::Setting::Gsm).dynamicCast(); - if (gsmSetting) { - gsmSetting->setHomeOnly(!roaming); // set roaming setting + NetworkManager::GsmSetting::Ptr gsmSetting = connection->settings()->setting(NetworkManager::Setting::Gsm).dynamicCast(); + if (gsmSetting) { + gsmSetting->setHomeOnly(!roaming); // set roaming setting - QDBusPendingReply reply = connection->update(connection->settings()->toMap()); - reply.waitForFinished(); - if (reply.isError()) { - qWarning() << QStringLiteral("Error updating connection settings for") << connection->uuid() << QStringLiteral(":") << reply.error().message() - << QStringLiteral("."); - CellularNetworkSettings::instance()->addMessage( - InlineMessage::Error, - i18n("Error updating connection settings for %1: %2.", connection->uuid(), reply.error().message())); - } else { - qDebug() << QStringLiteral("Successfully updated connection settings") << connection->uuid() << QStringLiteral("."); - } + QDBusReply reply = co_await connection->update(connection->settings()->toMap()); + if (reply.isValid()) { + qWarning() << QStringLiteral("Error updating connection settings for") << connection->uuid() << QStringLiteral(":") << reply.error().message() + << QStringLiteral("."); + CellularNetworkSettings::instance()->addMessage( + InlineMessage::Error, + i18n("Error updating connection settings for %1: %2.", connection->uuid(), reply.error().message())); + } else { + qDebug() << QStringLiteral("Successfully updated connection settings") << connection->uuid() << QStringLiteral("."); } - - // the connection uni has changed, refresh the profiles list - refreshProfiles(); - Q_EMIT activeConnectionUniChanged(); } + + // the connection uni has changed, refresh the profiles list + refreshProfiles(); + Q_EMIT activeConnectionUniChanged(); } bool Modem::hasSim() const @@ -287,11 +283,11 @@ void Modem::refreshProfiles() Q_EMIT profileListChanged(); } -void Modem::activateProfile(const QString &connectionUni) +QCoro::Task Modem::activateProfile(const QString &connectionUni) { if (!m_nmModem) { qWarning() << "Cannot activate profile since there is no NetworkManager modem"; - return; + co_return; } qDebug() << QStringLiteral("Activating profile on modem") << m_nmModem->uni() << QStringLiteral("for connection") << connectionUni << "."; @@ -313,28 +309,27 @@ void Modem::activateProfile(const QString &connectionUni) if (!con) { qDebug() << QStringLiteral("Connection") << connectionUni << QStringLiteral("not found."); - return; + co_return; } // activate connection manually // despite the documentation saying otherwise, activateConnection seems to need the DBus path, not uuid of the connection - QDBusPendingReply reply = NetworkManager::activateConnection(con->path(), m_nmModem->uni(), ""); - reply.waitForFinished(); - if (reply.isError()) { + QDBusReply reply = co_await NetworkManager::activateConnection(con->path(), m_nmModem->uni(), ""); + if (reply.isValid()) { qWarning() << QStringLiteral("Error activating connection:") << reply.error().message(); CellularNetworkSettings::instance()->addMessage(InlineMessage::Error, i18n("Error activating connection: %1", reply.error().message())); - return; + co_return; } // set roaming settings separately (since it changes the uni) - setIsRoaming(roaming); + co_await setIsRoaming(roaming); } -void Modem::addProfile(QString name, QString apn, QString username, QString password, QString networkType) +QCoro::Task Modem::addProfile(QString name, QString apn, QString username, QString password, QString networkType) { if (!m_nmModem) { qWarning() << "Cannot add profile since there is no NetworkManager modem"; - return; + co_return; } NetworkManager::ConnectionSettings::Ptr settings{new NetworkManager::ConnectionSettings(NetworkManager::ConnectionSettings::Gsm)}; @@ -353,9 +348,8 @@ void Modem::addProfile(QString name, QString apn, QString username, QString pass gsmSetting->setInitialized(true); - QDBusPendingReply reply = NetworkManager::addAndActivateConnection(settings->toMap(), m_nmModem->uni(), ""); - reply.waitForFinished(); - if (reply.isError()) { + QDBusReply reply = co_await NetworkManager::addAndActivateConnection(settings->toMap(), m_nmModem->uni(), ""); + if (reply.isValid()) { qWarning() << QStringLiteral("Error adding connection:") << reply.error().message(); CellularNetworkSettings::instance()->addMessage(InlineMessage::Error, i18n("Error adding connection: %1", reply.error().message())); } else { @@ -363,34 +357,33 @@ void Modem::addProfile(QString name, QString apn, QString username, QString pass } } -void Modem::removeProfile(const QString &connectionUni) +QCoro::Task Modem::removeProfile(const QString &connectionUni) { NetworkManager::Connection::Ptr con = NetworkManager::findConnectionByUuid(connectionUni); if (!con) { qWarning() << QStringLiteral("Could not find connection") << connectionUni << QStringLiteral("to update!"); - return; + co_return; } - QDBusPendingReply reply = con->remove(); - reply.waitForFinished(); - if (reply.isError()) { + QDBusReply reply = co_await con->remove(); + if (reply.isValid()) { qWarning() << QStringLiteral("Error removing connection") << reply.error().message(); CellularNetworkSettings::instance()->addMessage(InlineMessage::Error, i18n("Error removing connection: %1", reply.error().message())); } } -void Modem::updateProfile(QString connectionUni, QString name, QString apn, QString username, QString password, QString networkType) +QCoro::Task Modem::updateProfile(QString connectionUni, QString name, QString apn, QString username, QString password, QString networkType) { NetworkManager::Connection::Ptr con = NetworkManager::findConnectionByUuid(connectionUni); if (!con) { qWarning() << QStringLiteral("Could not find connection") << connectionUni << QStringLiteral("to update!"); - return; + co_return; } NetworkManager::ConnectionSettings::Ptr conSettings = con->settings(); if (!conSettings) { qWarning() << QStringLiteral("Could not find connection settings for") << connectionUni << QStringLiteral("to update!"); - return; + co_return; } conSettings->setId(name); @@ -405,9 +398,8 @@ void Modem::updateProfile(QString connectionUni, QString name, QString apn, QStr gsmSetting->setInitialized(true); - QDBusPendingReply reply = con->update(conSettings->toMap()); - reply.waitForFinished(); - if (reply.isError()) { + QDBusReply reply = con->update(conSettings->toMap()); + if (reply.isValid()) { qWarning() << QStringLiteral("Error updating connection settings for") << connectionUni << QStringLiteral(":") << reply.error().message() << QStringLiteral("."); CellularNetworkSettings::instance()->addMessage(InlineMessage::Error, diff --git a/kcms/cellularnetwork/modem.h b/kcms/cellularnetwork/modem.h index 0e82f87b..12fee4cf 100644 --- a/kcms/cellularnetwork/modem.h +++ b/kcms/cellularnetwork/modem.h @@ -23,6 +23,8 @@ #include #include +#include + class ProfileSettings; class Sim; class AvailableNetwork; @@ -55,7 +57,7 @@ public: QString uni() const; QString activeConnectionUni() const; - Q_INVOKABLE void reset(); + Q_INVOKABLE QCoro::Task reset(); bool mobileDataEnabled() const; void setMobileDataEnabled(bool enabled); @@ -63,16 +65,16 @@ public: bool needsAPNAdded() const; bool isRoaming() const; - void setIsRoaming(bool roaming); + QCoro::Task setIsRoaming(bool roaming); bool hasSim() const; // connection profiles QList &profileList(); void refreshProfiles(); - Q_INVOKABLE void activateProfile(const QString &connectionUni); - Q_INVOKABLE void addProfile(QString name, QString apn, QString username, QString password, QString networkType); - Q_INVOKABLE void removeProfile(const QString &connectionUni); - Q_INVOKABLE void updateProfile(QString connectionUni, QString name, QString apn, QString username, QString password, QString networkType); + Q_INVOKABLE QCoro::Task activateProfile(const QString &connectionUni); + Q_INVOKABLE QCoro::Task addProfile(QString name, QString apn, QString username, QString password, QString networkType); + Q_INVOKABLE QCoro::Task removeProfile(const QString &connectionUni); + Q_INVOKABLE QCoro::Task updateProfile(QString connectionUni, QString name, QString apn, QString username, QString password, QString networkType); Q_INVOKABLE void addDetectedProfileSettings(); // detect modem connection settings (ex. apn) and add a new connection QList sims(); diff --git a/kcms/cellularnetwork/sim.cpp b/kcms/cellularnetwork/sim.cpp index 95e91443..16d096a5 100644 --- a/kcms/cellularnetwork/sim.cpp +++ b/kcms/cellularnetwork/sim.cpp @@ -5,6 +5,8 @@ #include +#include + Sim::Sim(QObject *parent, Modem *modem, ModemManager::Sim::Ptr mmSim, ModemManager::Modem::Ptr mmModem, ModemManager::Modem3gpp::Ptr mmModem3gpp) : QObject{parent} , m_modem{modem} @@ -12,23 +14,27 @@ Sim::Sim(QObject *parent, Modem *modem, ModemManager::Sim::Ptr mmSim, ModemManag , m_mmModem{mmModem} , m_mmModem3gpp{mmModem3gpp} { - connect(m_mmSim.data(), &ModemManager::Sim::imsiChanged, this, [this]() -> void { - Q_EMIT imsiChanged(); - }); - connect(m_mmSim.data(), &ModemManager::Sim::operatorIdentifierChanged, this, [this]() -> void { - Q_EMIT operatorIdentifierChanged(); - }); - connect(m_mmSim.data(), &ModemManager::Sim::operatorNameChanged, this, [this]() -> void { - Q_EMIT operatorNameChanged(); - }); - connect(m_mmSim.data(), &ModemManager::Sim::simIdentifierChanged, this, [this]() -> void { - Q_EMIT simIdentifierChanged(); - }); + if (m_mmSim) { + connect(m_mmSim.data(), &ModemManager::Sim::imsiChanged, this, [this]() -> void { + Q_EMIT imsiChanged(); + }); + connect(m_mmSim.data(), &ModemManager::Sim::operatorIdentifierChanged, this, [this]() -> void { + Q_EMIT operatorIdentifierChanged(); + }); + connect(m_mmSim.data(), &ModemManager::Sim::operatorNameChanged, this, [this]() -> void { + Q_EMIT operatorNameChanged(); + }); + connect(m_mmSim.data(), &ModemManager::Sim::simIdentifierChanged, this, [this]() -> void { + Q_EMIT simIdentifierChanged(); + }); + } - connect(m_mmModem.data(), &ModemManager::Modem::unlockRequiredChanged, this, [this]() -> void { - Q_EMIT lockedChanged(); - Q_EMIT lockedReasonChanged(); - }); + if (m_mmModem) { + connect(m_mmModem.data(), &ModemManager::Modem::unlockRequiredChanged, this, [this]() -> void { + Q_EMIT lockedChanged(); + Q_EMIT lockedReasonChanged(); + }); + } if (m_mmModem3gpp) { connect(m_mmModem3gpp.data(), &ModemManager::Modem3gpp::enabledFacilityLocksChanged, this, [this]() -> void { @@ -49,16 +55,20 @@ bool Sim::pinEnabled() int Sim::unlockRetriesLeft() { - return m_mmModem->unlockRetries()[MM_MODEM_LOCK_SIM_PIN]; + return m_mmModem && m_mmModem->unlockRetries()[MM_MODEM_LOCK_SIM_PIN]; } bool Sim::locked() { - return m_mmModem->unlockRequired() == MM_MODEM_LOCK_SIM_PIN; + return m_mmModem && m_mmModem->unlockRequired() == MM_MODEM_LOCK_SIM_PIN; } QString Sim::lockedReason() { + if (!m_mmModem) { + return {}; + } + switch (m_mmModem->unlockRequired()) { case MM_MODEM_LOCK_UNKNOWN: return i18n("Lock reason unknown."); @@ -95,32 +105,32 @@ QString Sim::lockedReason() case MM_MODEM_LOCK_PH_NETSUB_PUK: return i18n("Modem requires the network subset PUK code."); } - return QString{}; + return {}; } QString Sim::imsi() { - return m_mmSim->imsi(); + return m_mmSim ? m_mmSim->imsi() : QString{}; } QString Sim::eid() { - return ""; // TODO add in mm-qt + return {}; // TODO add in mm-qt } QString Sim::operatorIdentifier() { - return m_mmSim->operatorIdentifier(); + return m_mmSim ? m_mmSim->operatorIdentifier() : QString{}; } QString Sim::operatorName() { - return m_mmSim->operatorName(); + return m_mmSim ? m_mmSim->operatorName() : QString{}; } QString Sim::simIdentifier() { - return m_mmSim->simIdentifier(); + return m_mmSim ? m_mmSim->simIdentifier() : QString{}; } QStringList Sim::emergencyNumbers() @@ -130,7 +140,7 @@ QStringList Sim::emergencyNumbers() QString Sim::uni() { - return m_mmSim->uni(); + return m_mmSim ? m_mmSim->uni() : QString{}; } QString Sim::displayId() @@ -145,47 +155,47 @@ Modem *Sim::modem() return m_modem; } -void Sim::togglePinEnabled(const QString &pin) +QCoro::Task Sim::togglePinEnabled(const QString &pin) { bool isPinEnabled = pinEnabled(); - QDBusPendingReply reply = m_mmSim->enablePin(pin, !isPinEnabled); - reply.waitForFinished(); - if (reply.isError()) { + QDBusReply reply = co_await m_mmSim->enablePin(pin, !isPinEnabled); + if (reply.isValid()) { qWarning() << QStringLiteral("Error toggling SIM lock to") << isPinEnabled << QStringLiteral(":") << reply.error().message(); CellularNetworkSettings::instance()->addMessage(InlineMessage::Error, i18n("Error toggling SIM lock: %1", reply.error().message())); } } -void Sim::changePin(const QString &oldPin, const QString &newPin) +QCoro::Task Sim::changePin(const QString &oldPin, const QString &newPin) { - QDBusPendingReply reply = m_mmSim->changePin(oldPin, newPin); - reply.waitForFinished(); - if (reply.isError()) { + QDBusReply reply = co_await m_mmSim->changePin(oldPin, newPin); + if (reply.isValid()) { qWarning() << QStringLiteral("Error changing the PIN:") << reply.error().message(); CellularNetworkSettings::instance()->addMessage(InlineMessage::Error, i18n("Error changing the PIN: %1", reply.error().message())); } } -void Sim::sendPin(const QString &pin) +QCoro::Task Sim::sendPin(const QString &pin) { - if (m_mmModem->unlockRequired() != MM_MODEM_LOCK_NONE) { - QDBusPendingReply reply = m_mmSim->sendPin(pin); - reply.waitForFinished(); - if (reply.isError()) { - qWarning() << QStringLiteral("Error sending the PIN:") << reply.error().message(); - CellularNetworkSettings::instance()->addMessage(InlineMessage::Error, i18n("Error sending the PIN: %1", reply.error().message())); - } + if (!m_mmModem || !m_mmSim || m_mmModem->unlockRequired() == MM_MODEM_LOCK_NONE) { + co_return; + } + + QDBusReply reply = co_await m_mmSim->sendPin(pin); + if (reply.isValid()) { + qWarning() << QStringLiteral("Error sending the PIN:") << reply.error().message(); + CellularNetworkSettings::instance()->addMessage(InlineMessage::Error, i18n("Error sending the PIN: %1", reply.error().message())); } } -void Sim::sendPuk(const QString &pin, const QString &puk) +QCoro::Task Sim::sendPuk(const QString &pin, const QString &puk) { - if (m_mmModem->unlockRequired() != MM_MODEM_LOCK_NONE) { - QDBusPendingReply reply = m_mmSim->sendPuk(pin, puk); - reply.waitForFinished(); - if (reply.isError()) { - qWarning() << QStringLiteral("Error sending the PUK:") << reply.error().message(); - CellularNetworkSettings::instance()->addMessage(InlineMessage::Error, i18n("Error sending the PUK: %1", reply.error().message())); - } + if (!m_mmModem || !m_mmSim || m_mmModem->unlockRequired() != MM_MODEM_LOCK_NONE) { + co_return; + } + + QDBusReply reply = co_await m_mmSim->sendPuk(pin, puk); + if (reply.isValid()) { + qWarning() << QStringLiteral("Error sending the PUK:") << reply.error().message(); + CellularNetworkSettings::instance()->addMessage(InlineMessage::Error, i18n("Error sending the PUK: %1", reply.error().message())); } } diff --git a/kcms/cellularnetwork/sim.h b/kcms/cellularnetwork/sim.h index d0ac1ff8..8d44b920 100644 --- a/kcms/cellularnetwork/sim.h +++ b/kcms/cellularnetwork/sim.h @@ -20,6 +20,8 @@ #include #include +#include + class Modem; class Sim : public QObject @@ -62,10 +64,10 @@ public: QString displayId(); Modem *modem(); - Q_INVOKABLE void togglePinEnabled(const QString &pin); - Q_INVOKABLE void changePin(const QString &oldPin, const QString &newPin); - Q_INVOKABLE void sendPin(const QString &pin); - Q_INVOKABLE void sendPuk(const QString &pin, const QString &puk); + Q_INVOKABLE QCoro::Task togglePinEnabled(const QString &pin); + Q_INVOKABLE QCoro::Task changePin(const QString &oldPin, const QString &newPin); + Q_INVOKABLE QCoro::Task sendPin(const QString &pin); + Q_INVOKABLE QCoro::Task sendPuk(const QString &pin, const QString &puk); Q_SIGNALS: void enabledChanged(); diff --git a/kcms/cellularnetwork/ui/main.qml b/kcms/cellularnetwork/ui/main.qml index 5967b0f0..ef48bbd3 100644 --- a/kcms/cellularnetwork/ui/main.qml +++ b/kcms/cellularnetwork/ui/main.qml @@ -89,7 +89,7 @@ KCM.SimpleKCM { checked = shouldBeChecked; } - enabled: kcm.selectedModem.mobileDataSupported && !kcm.selectedModem.needsAPNAdded + enabled: kcm.selectedModem && kcm.selectedModem.mobileDataSupported && !kcm.selectedModem.needsAPNAdded checked: shouldBeChecked onCheckedChanged: {