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) |
21 | Q_GLOBAL_STATIC(NetworkManager::SettingsPrivate, globalSettings) |
22 | |
23 | NetworkManager::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 | |
52 | void 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 | |
71 | NetworkManager::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 | |
85 | NetworkManager::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 | |
99 | QString NetworkManager::SettingsPrivate::hostname() const |
100 | { |
101 | return m_hostname; |
102 | } |
103 | |
104 | bool NetworkManager::SettingsPrivate::canModify() const |
105 | { |
106 | return m_canModify; |
107 | } |
108 | |
109 | QDBusPendingReply<QDBusObjectPath> NetworkManager::SettingsPrivate::addConnection(const NMVariantMapMap &connection) |
110 | { |
111 | return iface.AddConnection(connection); |
112 | } |
113 | |
114 | QDBusPendingReply<QDBusObjectPath> NetworkManager::SettingsPrivate::addConnectionUnsaved(const NMVariantMapMap &connection) |
115 | { |
116 | return iface.AddConnectionUnsaved(connection); |
117 | } |
118 | |
119 | QDBusPendingReply<bool, QStringList> NetworkManager::SettingsPrivate::loadConnections(const QStringList &filenames) |
120 | { |
121 | return iface.LoadConnections(filenames); |
122 | } |
123 | |
124 | QDBusPendingReply<bool> NetworkManager::SettingsPrivate::reloadConnections() |
125 | { |
126 | return iface.ReloadConnections(); |
127 | } |
128 | |
129 | void NetworkManager::SettingsPrivate::initNotifier() |
130 | { |
131 | notifier(); |
132 | } |
133 | |
134 | void NetworkManager::SettingsPrivate::saveHostname(const QString &hostname) |
135 | { |
136 | iface.SaveHostname(hostname); |
137 | } |
138 | |
139 | void 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 | |
149 | void 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 | |
170 | void 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 | |
180 | NetworkManager::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 | |
199 | void NetworkManager::SettingsPrivate::onConnectionRemoved(const QDBusObjectPath &path) |
200 | { |
201 | onConnectionRemoved(path.path()); |
202 | } |
203 | |
204 | void NetworkManager::SettingsPrivate::onConnectionRemoved(const QString &path) |
205 | { |
206 | connections.remove(key: path); |
207 | Q_EMIT connectionRemoved(path); |
208 | } |
209 | |
210 | void NetworkManager::SettingsPrivate::daemonUnregistered() |
211 | { |
212 | connections.clear(); |
213 | } |
214 | |
215 | NetworkManager::Connection::List NetworkManager::listConnections() |
216 | { |
217 | return globalSettings->listConnections(); |
218 | } |
219 | |
220 | NetworkManager::Connection::Ptr NetworkManager::findConnectionByUuid(const QString &uuid) |
221 | { |
222 | return globalSettings->findConnectionByUuid(uuid); |
223 | } |
224 | |
225 | NetworkManager::Connection::Ptr NetworkManager::findConnection(const QString &path) |
226 | { |
227 | return globalSettings->findRegisteredConnection(path); |
228 | } |
229 | |
230 | QDBusPendingReply<QDBusObjectPath> NetworkManager::addConnection(const NMVariantMapMap &connection) |
231 | { |
232 | return globalSettings->addConnection(connection); |
233 | } |
234 | |
235 | QDBusPendingReply<QDBusObjectPath> NetworkManager::addConnectionUnsaved(const NMVariantMapMap &connection) |
236 | { |
237 | return globalSettings->addConnectionUnsaved(connection); |
238 | } |
239 | |
240 | QDBusPendingReply<bool, QStringList> NetworkManager::loadConnections(const QStringList &filenames) |
241 | { |
242 | return globalSettings->loadConnections(filenames); |
243 | } |
244 | |
245 | QDBusPendingReply<bool> NetworkManager::reloadConnections() |
246 | { |
247 | return globalSettings->reloadConnections(); |
248 | } |
249 | |
250 | void NetworkManager::saveHostname(const QString &hostname) |
251 | { |
252 | globalSettings->saveHostname(hostname); |
253 | } |
254 | |
255 | bool NetworkManager::canModify() |
256 | { |
257 | return globalSettings->canModify(); |
258 | } |
259 | |
260 | QString NetworkManager::hostname() |
261 | { |
262 | return globalSettings->hostname(); |
263 | } |
264 | |
265 | NetworkManager::SettingsNotifier *NetworkManager::settingsNotifier() |
266 | { |
267 | return globalSettings; |
268 | } |
269 | |
270 | #include "moc_settings.cpp" |
271 | #include "moc_settings_p.cpp" |
272 | |