1/*
2 SPDX-FileCopyrightText: 2011-2013 Lamarque Souza <lamarque@kde.org>
3 SPDX-FileCopyrightText: 2013 Jan Grulich <jgrulich@redhat.com>
4
5 SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
6*/
7
8#include "settings.h"
9#include "macros.h"
10#include "manager_p.h"
11#include "settings_p.h"
12
13#include <QDBusObjectPath>
14#include <QTimer>
15
16#include <nm-setting-connection.h>
17
18#include "nmdebug.h"
19
20// NM_GLOBAL_STATIC(NetworkManager::SettingsPrivate, globalSettings)
21Q_GLOBAL_STATIC(NetworkManager::SettingsPrivate, globalSettings)
22
23NetworkManager::SettingsPrivate::SettingsPrivate()
24#ifdef NMQT_STATIC
25 : iface(NetworkManagerPrivate::DBUS_SERVICE, NetworkManagerPrivate::DBUS_SETTINGS_PATH, QDBusConnection::sessionBus())
26#else
27 : iface(NetworkManagerPrivate::DBUS_SERVICE, NetworkManagerPrivate::DBUS_SETTINGS_PATH, QDBusConnection::systemBus())
28#endif
29 , m_canModify(true)
30{
31 QDBusConnection::systemBus().connect(service: NetworkManagerPrivate::DBUS_SERVICE,
32 path: NetworkManagerPrivate::DBUS_SETTINGS_PATH,
33 interface: NetworkManagerPrivate::FDO_DBUS_PROPERTIES,
34 name: QLatin1String("PropertiesChanged"),
35 receiver: this,
36 SLOT(dbusPropertiesChanged(QString, QVariantMap, QStringList)));
37 connect(sender: &iface, signal: &OrgFreedesktopNetworkManagerSettingsInterface::NewConnection, context: this, slot: &SettingsPrivate::onConnectionAdded);
38 connect(sender: &iface,
39 signal: &OrgFreedesktopNetworkManagerSettingsInterface::ConnectionRemoved,
40 context: this,
41 slot: static_cast<void (SettingsPrivate::*)(const QDBusObjectPath &)>(&SettingsPrivate::onConnectionRemoved));
42 init();
43 // This class is a friend of NetworkManagerPrivate thus initted there too
44 // because of the init chain we must follow,
45 // But if this class is used first we need to make sure the
46 // NetworkManagerPrivate also get created so we have its signals for
47 // when the daemon dies, we just can not call it directly here or
48 // we will have a constructor infinite loop
49 QTimer::singleShot(msec: 0, receiver: this, SLOT(initNotifier()));
50}
51
52void NetworkManager::SettingsPrivate::init()
53{
54 const QList<QDBusObjectPath> connectionList = iface.connections();
55 qCDebug(NMQT) << "Connections list";
56 for (const QDBusObjectPath &connection : connectionList) {
57 if (!connections.contains(key: connection.path())) {
58 connections.insert(key: connection.path(), value: Connection::Ptr());
59 Q_EMIT connectionAdded(path: connection.path());
60 qCDebug(NMQT) << " " << connection.path();
61 }
62 }
63
64 // Get all Setting's properties at once
65 QVariantMap initialProperties = NetworkManagerPrivate::retrieveInitialProperties(interfaceName: iface.staticInterfaceName(), path: NetworkManagerPrivate::DBUS_SETTINGS_PATH);
66 if (!initialProperties.isEmpty()) {
67 propertiesChanged(properties: initialProperties);
68 }
69}
70
71NetworkManager::Connection::List NetworkManager::SettingsPrivate::listConnections()
72{
73 NetworkManager::Connection::List list;
74 QMap<QString, Connection::Ptr>::const_iterator i = connections.constBegin();
75 while (i != connections.constEnd()) {
76 NetworkManager::Connection::Ptr connection = findRegisteredConnection(i.key());
77 if (connection) {
78 list << connection;
79 }
80 ++i;
81 }
82 return list;
83}
84
85NetworkManager::Connection::Ptr NetworkManager::SettingsPrivate::findConnectionByUuid(const QString &uuid)
86{
87 QMap<QString, Connection::Ptr>::const_iterator i = connections.constBegin();
88 while (i != connections.constEnd()) {
89 NetworkManager::Connection::Ptr connection = findRegisteredConnection(i.key());
90 if (connection && connection->uuid() == uuid) {
91 return connection;
92 }
93 ++i;
94 }
95
96 return NetworkManager::Connection::Ptr();
97}
98
99QString NetworkManager::SettingsPrivate::hostname() const
100{
101 return m_hostname;
102}
103
104bool NetworkManager::SettingsPrivate::canModify() const
105{
106 return m_canModify;
107}
108
109QDBusPendingReply<QDBusObjectPath> NetworkManager::SettingsPrivate::addConnection(const NMVariantMapMap &connection)
110{
111 return iface.AddConnection(connection);
112}
113
114QDBusPendingReply<QDBusObjectPath> NetworkManager::SettingsPrivate::addConnectionUnsaved(const NMVariantMapMap &connection)
115{
116 return iface.AddConnectionUnsaved(connection);
117}
118
119QDBusPendingReply<bool, QStringList> NetworkManager::SettingsPrivate::loadConnections(const QStringList &filenames)
120{
121 return iface.LoadConnections(filenames);
122}
123
124QDBusPendingReply<bool> NetworkManager::SettingsPrivate::reloadConnections()
125{
126 return iface.ReloadConnections();
127}
128
129void NetworkManager::SettingsPrivate::initNotifier()
130{
131 notifier();
132}
133
134void NetworkManager::SettingsPrivate::saveHostname(const QString &hostname)
135{
136 iface.SaveHostname(hostname);
137}
138
139void NetworkManager::SettingsPrivate::dbusPropertiesChanged(const QString &interfaceName,
140 const QVariantMap &properties,
141 const QStringList &invalidatedProperties)
142{
143 Q_UNUSED(invalidatedProperties);
144 if (interfaceName == QLatin1String("org.freedesktop.NetworkManager.Settings")) {
145 propertiesChanged(properties);
146 }
147}
148
149void NetworkManager::SettingsPrivate::propertiesChanged(const QVariantMap &properties)
150{
151 QVariantMap::const_iterator it = properties.constBegin();
152 while (it != properties.constEnd()) {
153 const QString property = it.key();
154 if (property == QLatin1String("CanModify")) {
155 m_canModify = it->toBool();
156 Q_EMIT canModifyChanged(canModify: m_canModify);
157 } else if (property == QLatin1String("Hostname")) {
158 m_hostname = it->toString();
159 Q_EMIT hostnameChanged(hostname: m_hostname);
160 } else if (property == QLatin1String("Connections")) {
161 // will never get here in runtime NM < 0.9.10
162 // TODO some action??
163 } else {
164 qCWarning(NMQT) << Q_FUNC_INFO << "Unhandled property" << property;
165 }
166 ++it;
167 }
168}
169
170void NetworkManager::SettingsPrivate::onConnectionAdded(const QDBusObjectPath &path)
171{
172 const QString id = path.path();
173 if (connections.contains(key: id)) {
174 return;
175 }
176 connections.insert(key: id, value: Connection::Ptr());
177 Q_EMIT connectionAdded(path: id);
178}
179
180NetworkManager::Connection::Ptr NetworkManager::SettingsPrivate::findRegisteredConnection(const QString &path)
181{
182 Connection::Ptr ret;
183 if (!path.isEmpty()) {
184 bool contains = connections.contains(key: path);
185 if (contains && connections.value(key: path)) {
186 ret = connections.value(key: path);
187 } else {
188 ret = Connection::Ptr(new Connection(path), &QObject::deleteLater);
189 connections[path] = ret;
190 connect(sender: ret.data(), SIGNAL(removed(QString)), receiver: this, SLOT(onConnectionRemoved(QString)));
191 if (!contains) {
192 Q_EMIT connectionAdded(path);
193 }
194 }
195 }
196 return ret;
197}
198
199void NetworkManager::SettingsPrivate::onConnectionRemoved(const QDBusObjectPath &path)
200{
201 onConnectionRemoved(path.path());
202}
203
204void NetworkManager::SettingsPrivate::onConnectionRemoved(const QString &path)
205{
206 connections.remove(key: path);
207 Q_EMIT connectionRemoved(path);
208}
209
210void NetworkManager::SettingsPrivate::daemonUnregistered()
211{
212 connections.clear();
213}
214
215NetworkManager::Connection::List NetworkManager::listConnections()
216{
217 return globalSettings->listConnections();
218}
219
220NetworkManager::Connection::Ptr NetworkManager::findConnectionByUuid(const QString &uuid)
221{
222 return globalSettings->findConnectionByUuid(uuid);
223}
224
225NetworkManager::Connection::Ptr NetworkManager::findConnection(const QString &path)
226{
227 return globalSettings->findRegisteredConnection(path);
228}
229
230QDBusPendingReply<QDBusObjectPath> NetworkManager::addConnection(const NMVariantMapMap &connection)
231{
232 return globalSettings->addConnection(connection);
233}
234
235QDBusPendingReply<QDBusObjectPath> NetworkManager::addConnectionUnsaved(const NMVariantMapMap &connection)
236{
237 return globalSettings->addConnectionUnsaved(connection);
238}
239
240QDBusPendingReply<bool, QStringList> NetworkManager::loadConnections(const QStringList &filenames)
241{
242 return globalSettings->loadConnections(filenames);
243}
244
245QDBusPendingReply<bool> NetworkManager::reloadConnections()
246{
247 return globalSettings->reloadConnections();
248}
249
250void NetworkManager::saveHostname(const QString &hostname)
251{
252 globalSettings->saveHostname(hostname);
253}
254
255bool NetworkManager::canModify()
256{
257 return globalSettings->canModify();
258}
259
260QString NetworkManager::hostname()
261{
262 return globalSettings->hostname();
263}
264
265NetworkManager::SettingsNotifier *NetworkManager::settingsNotifier()
266{
267 return globalSettings;
268}
269
270#include "moc_settings.cpp"
271#include "moc_settings_p.cpp"
272

source code of networkmanager-qt/src/settings.cpp