| 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 | |