File indexing completed on 2024-05-19 05:37:50

0001 /*
0002     SPDX-FileCopyrightText: 2009 Petri Damsten <damu@iki.fi>
0003 
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 #include "geolocation.h"
0008 
0009 #include <limits.h>
0010 
0011 #include <KPluginMetaData>
0012 #include <NetworkManagerQt/Manager>
0013 #include <QDebug>
0014 
0015 static const char SOURCE[] = "location";
0016 
0017 Geolocation::Geolocation(QObject *parent)
0018     : Plasma5Support::DataEngine(parent)
0019 {
0020     setMinimumPollingInterval(500);
0021     connect(NetworkManager::notifier(), &NetworkManager::Notifier::networkingEnabledChanged, this, &Geolocation::networkStatusChanged);
0022     connect(NetworkManager::notifier(), &NetworkManager::Notifier::wirelessEnabledChanged, this, &Geolocation::networkStatusChanged);
0023     m_updateTimer.setInterval(100);
0024     m_updateTimer.setSingleShot(true);
0025     connect(&m_updateTimer, &QTimer::timeout, this, &Geolocation::actuallySetData);
0026     m_networkChangedTimer.setInterval(100);
0027     m_networkChangedTimer.setSingleShot(true);
0028     connect(&m_networkChangedTimer, &QTimer::timeout, this, [this] {
0029         updatePlugins(GeolocationProvider::NetworkConnected);
0030     });
0031     init();
0032 }
0033 
0034 void Geolocation::init()
0035 {
0036     // TODO: should this be delayed even further, e.g. when the source is requested?
0037     const QList<KPluginMetaData> offers = KPluginMetaData::findPlugins("plasma5support/geolocationprovider", {}, KPluginMetaData::AllowEmptyMetaData);
0038     for (const auto &metaData : offers) {
0039         auto result = KPluginFactory::instantiatePlugin<GeolocationProvider>(metaData, this);
0040         if (result) {
0041             GeolocationProvider *plugin = result.plugin;
0042             m_plugins << plugin;
0043             plugin->init(&m_data, &m_accuracy);
0044             connect(plugin, &GeolocationProvider::updated, this, &Geolocation::pluginUpdated);
0045             connect(plugin, &GeolocationProvider::availabilityChanged, this, &Geolocation::pluginAvailabilityChanged);
0046         } else {
0047             qDebug() << "Failed to load GeolocationProvider:" << metaData.fileName() << result.errorString;
0048         }
0049     }
0050 }
0051 
0052 Geolocation::~Geolocation()
0053 {
0054     qDeleteAll(m_plugins);
0055 }
0056 
0057 QStringList Geolocation::sources() const
0058 {
0059     return QStringList() << SOURCE;
0060 }
0061 
0062 bool Geolocation::updateSourceEvent(const QString &name)
0063 {
0064     // qDebug() << name;
0065     if (name == SOURCE) {
0066         return updatePlugins(GeolocationProvider::SourceEvent);
0067     }
0068 
0069     return false;
0070 }
0071 
0072 bool Geolocation::updatePlugins(GeolocationProvider::UpdateTriggers triggers)
0073 {
0074     bool changed = false;
0075 
0076     for (GeolocationProvider *plugin : std::as_const(m_plugins)) {
0077         changed = plugin->requestUpdate(triggers) || changed;
0078     }
0079 
0080     if (changed) {
0081         m_updateTimer.start();
0082     }
0083 
0084     return changed;
0085 }
0086 
0087 bool Geolocation::sourceRequestEvent(const QString &name)
0088 {
0089     qDebug() << name;
0090     if (name == SOURCE) {
0091         updatePlugins(GeolocationProvider::ForcedUpdate);
0092         setData(SOURCE, m_data);
0093         return true;
0094     }
0095 
0096     return false;
0097 }
0098 
0099 void Geolocation::networkStatusChanged(bool isOnline)
0100 {
0101     qDebug() << "network status changed";
0102     if (isOnline) {
0103         m_networkChangedTimer.start();
0104     }
0105 }
0106 
0107 void Geolocation::pluginAvailabilityChanged(GeolocationProvider *provider)
0108 {
0109     m_data.clear();
0110     m_accuracy.clear();
0111 
0112     provider->requestUpdate(GeolocationProvider::ForcedUpdate);
0113 
0114     bool changed = false;
0115     for (GeolocationProvider *plugin : std::as_const(m_plugins)) {
0116         changed = plugin->populateSharedData() || changed;
0117     }
0118 
0119     if (changed) {
0120         m_updateTimer.start();
0121     }
0122 }
0123 
0124 void Geolocation::pluginUpdated()
0125 {
0126     m_updateTimer.start();
0127 }
0128 
0129 void Geolocation::actuallySetData()
0130 {
0131     setData(SOURCE, m_data);
0132 }
0133 
0134 K_PLUGIN_CLASS_WITH_JSON(Geolocation, "plasma-dataengine-geolocation.json")
0135 
0136 #include "geolocation.moc"