diff --git a/CMakeLists.txt b/CMakeLists.txt index 907c00836..40350b22f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -13,7 +13,7 @@ set(CMAKE_MODULE_PATH ${ECM_MODULE_PATH} ${ECM_KDE_MODULE_DIR}) find_package(KF5 ${KF5_MIN_VERSION} REQUIRED COMPONENTS Plasma DocTools Runner JsEmbed NotifyConfig Su NewStuff Wallet KCMUtils - IdleTime Declarative TextWidgets KDELibs4Support Crash GlobalAccel) + IdleTime Declarative TextWidgets KDELibs4Support Crash GlobalAccel NetworkManagerQt) find_package(KF5XmlRpcClient REQUIRED) # WARNING PlasmaQuick provides unversioned CMake config diff --git a/dataengines/geolocation/CMakeLists.txt b/dataengines/geolocation/CMakeLists.txt index 1d6834a03..7a477c1cf 100644 --- a/dataengines/geolocation/CMakeLists.txt +++ b/dataengines/geolocation/CMakeLists.txt @@ -31,6 +31,7 @@ target_link_libraries(plasma_engine_geolocation KF5::Plasma KF5::CoreAddons KF5::KIOCore + KF5::NetworkManagerQt KF5::Service KF5::Solid) kcoreaddons_desktop_to_json(plasma_engine_geolocation plasma-dataengine-geolocation.desktop) @@ -43,7 +44,7 @@ install(FILES plasma-geolocationprovider.desktop DESTINATION ${KDE_INSTALL_KSERV set(plasma_geolocation_ip_SRCS location_ip.cpp) add_library(plasma-geolocation-ip MODULE ${plasma_geolocation_ip_SRCS}) -target_link_libraries(plasma-geolocation-ip plasma-geolocation-interface KF5::KIOCore) +target_link_libraries(plasma-geolocation-ip plasma-geolocation-interface KF5::KIOCore KF5::NetworkManagerQt) install(FILES plasma-geolocation-ip.desktop DESTINATION ${KDE_INSTALL_KSERVICES5DIR}) install(TARGETS plasma-geolocation-ip DESTINATION ${KDE_INSTALL_PLUGINDIR}) diff --git a/dataengines/geolocation/geolocation.cpp b/dataengines/geolocation/geolocation.cpp index e02060e15..678f25f4d 100644 --- a/dataengines/geolocation/geolocation.cpp +++ b/dataengines/geolocation/geolocation.cpp @@ -22,20 +22,27 @@ #include #include #include +#include static const char SOURCE[] = "location"; Geolocation::Geolocation(QObject* parent, const QVariantList& args) : Plasma::DataEngine(parent, args) - , m_networkManager(new QNetworkConfigurationManager(this)) { Q_UNUSED(args) setMinimumPollingInterval(500); - connect(m_networkManager, SIGNAL(onlineStateChanged(bool)), - this, SLOT(networkStatusChanged(bool))); + connect(NetworkManager::notifier(), &NetworkManager::Notifier::networkingEnabledChanged, this, &Geolocation::networkStatusChanged); + connect(NetworkManager::notifier(), &NetworkManager::Notifier::wirelessEnabledChanged, this, &Geolocation::networkStatusChanged); m_updateTimer.setInterval(100); m_updateTimer.setSingleShot(true); connect(&m_updateTimer, SIGNAL(timeout()), this, SLOT(actuallySetData())); + m_networkChangedTimer.setInterval(100); + m_networkChangedTimer.setSingleShot(true); + connect(&m_networkChangedTimer, &QTimer::timeout, this, + [this] { + updatePlugins(GeolocationProvider::NetworkConnected); + } + ); init(); } @@ -111,7 +118,7 @@ void Geolocation::networkStatusChanged(bool isOnline) { qDebug() << "network status changed"; if (isOnline) { - updatePlugins(GeolocationProvider::NetworkConnected); + m_networkChangedTimer.start(); } } diff --git a/dataengines/geolocation/geolocation.h b/dataengines/geolocation/geolocation.h index fcc95086b..dbf3a7b81 100644 --- a/dataengines/geolocation/geolocation.h +++ b/dataengines/geolocation/geolocation.h @@ -25,7 +25,6 @@ #include "geolocationprovider.h" class GeolocationProvider; -class QNetworkConfigurationManager; class Geolocation : public Plasma::DataEngine { @@ -51,9 +50,9 @@ class Geolocation : public Plasma::DataEngine private: Data m_data; EntryAccuracy m_accuracy; - QNetworkConfigurationManager *m_networkManager; QList m_plugins; QTimer m_updateTimer; + QTimer m_networkChangedTimer; }; #endif diff --git a/dataengines/geolocation/location_ip.cpp b/dataengines/geolocation/location_ip.cpp index 3a13dc301..70556102a 100644 --- a/dataengines/geolocation/location_ip.cpp +++ b/dataengines/geolocation/location_ip.cpp @@ -27,6 +27,9 @@ #include #include #include +#include +#include +#include class Ip::Private : public QObject { Q_OBJECT @@ -131,11 +134,45 @@ Ip::~Ip() delete d; } +static QJsonArray accessPoints() +{ + QJsonArray wifiAccessPoints; + const KConfigGroup config = KSharedConfig::openConfig()->group(QStringLiteral("org.kde.plasma.geolocation.ip")); + if (!NetworkManager::isWirelessEnabled() || !config.readEntry("Wifi", false)) { + return wifiAccessPoints; + } + for (const auto &device : NetworkManager::networkInterfaces()) { + QSharedPointer wifi = qSharedPointerDynamicCast(device); + if (!wifi) { + continue; + } + for (const auto &network : wifi->networks()) { + const QString &ssid = network->ssid(); + if (ssid.isEmpty() || ssid.endsWith(QLatin1String("_nomap"))) { + // skip hidden SSID and networks with "_nomap" + continue; + } + for (const auto &accessPoint : network->accessPoints()) { + wifiAccessPoints.append(QJsonObject{{QStringLiteral("macAddress"), accessPoint->hardwareAddress()}}); + } + } + } + return wifiAccessPoints; +} + void Ip::update() { d->clear(); - // TODO: add wifi data if available - const QByteArray postData = QByteArrayLiteral("{}"); + if (!NetworkManager::isNetworkingEnabled()) { + setData(Plasma::DataEngine::Data()); + return; + } + const QJsonArray wifiAccessPoints = accessPoints(); + QJsonObject request; + if (wifiAccessPoints.count() >= 2) { + request.insert(QStringLiteral("wifiAccessPoints"), wifiAccessPoints); + } + const QByteArray postData = QJsonDocument(request).toJson(QJsonDocument::Compact); const QString apiKey = QStringLiteral("60e8eae6-3988-4ada-ad48-2cfddddf216b"); KIO::TransferJob *datajob = KIO::http_post(QUrl(QStringLiteral("https://location.services.mozilla.com/v1/geolocate?key=%1").arg(apiKey)), postData,