1 /*
2 SPDX-FileCopyrightText: 2009 Petri Damsten <damu@iki.fi>
3
4 SPDX-License-Identifier: GPL-2.0-or-later
5 */
6
7 #include "geolocation.h"
8
9 #include <limits.h>
10
11 #include <KPluginMetaData>
12 #include <NetworkManagerQt/Manager>
13 #include <QDebug>
14 #include <QNetworkConfigurationManager>
15
16 static const char SOURCE[] = "location";
17
Geolocation(QObject * parent,const QVariantList & args)18 Geolocation::Geolocation(QObject *parent, const QVariantList &args)
19 : Plasma::DataEngine(parent, args)
20 {
21 setMinimumPollingInterval(500);
22 connect(NetworkManager::notifier(), &NetworkManager::Notifier::networkingEnabledChanged, this, &Geolocation::networkStatusChanged);
23 connect(NetworkManager::notifier(), &NetworkManager::Notifier::wirelessEnabledChanged, this, &Geolocation::networkStatusChanged);
24 m_updateTimer.setInterval(100);
25 m_updateTimer.setSingleShot(true);
26 connect(&m_updateTimer, &QTimer::timeout, this, &Geolocation::actuallySetData);
27 m_networkChangedTimer.setInterval(100);
28 m_networkChangedTimer.setSingleShot(true);
29 connect(&m_networkChangedTimer, &QTimer::timeout, this, [this] {
30 updatePlugins(GeolocationProvider::NetworkConnected);
31 });
32 init();
33 }
34
init()35 void Geolocation::init()
36 {
37 // TODO: should this be delayed even further, e.g. when the source is requested?
38 const QVector<KPluginMetaData> offers = KPluginMetaData::findPlugins("plasma/geolocationprovider");
39 for (const auto &metaData : offers) {
40 auto result = KPluginFactory::instantiatePlugin<GeolocationProvider>(metaData, this);
41 if (result) {
42 GeolocationProvider *plugin = result.plugin;
43 m_plugins << plugin;
44 plugin->init(&m_data, &m_accuracy);
45 connect(plugin, &GeolocationProvider::updated, this, &Geolocation::pluginUpdated);
46 connect(plugin, &GeolocationProvider::availabilityChanged, this, &Geolocation::pluginAvailabilityChanged);
47 } else {
48 qDebug() << "Failed to load GeolocationProvider:" << metaData.fileName() << result.errorString;
49 }
50 }
51 }
52
~Geolocation()53 Geolocation::~Geolocation()
54 {
55 qDeleteAll(m_plugins);
56 }
57
sources() const58 QStringList Geolocation::sources() const
59 {
60 return QStringList() << SOURCE;
61 }
62
updateSourceEvent(const QString & name)63 bool Geolocation::updateSourceEvent(const QString &name)
64 {
65 // qDebug() << name;
66 if (name == SOURCE) {
67 return updatePlugins(GeolocationProvider::SourceEvent);
68 }
69
70 return false;
71 }
72
updatePlugins(GeolocationProvider::UpdateTriggers triggers)73 bool Geolocation::updatePlugins(GeolocationProvider::UpdateTriggers triggers)
74 {
75 bool changed = false;
76
77 for (GeolocationProvider *plugin : qAsConst(m_plugins)) {
78 changed = plugin->requestUpdate(triggers) || changed;
79 }
80
81 if (changed) {
82 m_updateTimer.start();
83 }
84
85 return changed;
86 }
87
sourceRequestEvent(const QString & name)88 bool Geolocation::sourceRequestEvent(const QString &name)
89 {
90 qDebug() << name;
91 if (name == SOURCE) {
92 updatePlugins(GeolocationProvider::ForcedUpdate);
93 setData(SOURCE, m_data);
94 return true;
95 }
96
97 return false;
98 }
99
networkStatusChanged(bool isOnline)100 void Geolocation::networkStatusChanged(bool isOnline)
101 {
102 qDebug() << "network status changed";
103 if (isOnline) {
104 m_networkChangedTimer.start();
105 }
106 }
107
pluginAvailabilityChanged(GeolocationProvider * provider)108 void Geolocation::pluginAvailabilityChanged(GeolocationProvider *provider)
109 {
110 m_data.clear();
111 m_accuracy.clear();
112
113 provider->requestUpdate(GeolocationProvider::ForcedUpdate);
114
115 bool changed = false;
116 for (GeolocationProvider *plugin : qAsConst(m_plugins)) {
117 changed = plugin->populateSharedData() || changed;
118 }
119
120 if (changed) {
121 m_updateTimer.start();
122 }
123 }
124
pluginUpdated()125 void Geolocation::pluginUpdated()
126 {
127 m_updateTimer.start();
128 }
129
actuallySetData()130 void Geolocation::actuallySetData()
131 {
132 setData(SOURCE, m_data);
133 }
134
135 K_PLUGIN_CLASS_WITH_JSON(Geolocation, "plasma-dataengine-geolocation.json")
136
137 #include "geolocation.moc"
138