File indexing completed on 2024-04-21 04:00:14

0001 /*
0002     SPDX-FileCopyrightText: 2011-2013 Lamarque Souza <lamarque@kde.org>
0003     SPDX-FileCopyrightText: 2013 Jan Grulich <jgrulich@redhat.com>
0004 
0005     SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
0006 */
0007 
0008 #include "settings.h"
0009 #include "macros.h"
0010 #include "manager_p.h"
0011 #include "settings_p.h"
0012 
0013 #include <QDBusObjectPath>
0014 #include <QTimer>
0015 
0016 #include <nm-setting-connection.h>
0017 
0018 #include "nmdebug.h"
0019 
0020 // NM_GLOBAL_STATIC(NetworkManager::SettingsPrivate, globalSettings)
0021 Q_GLOBAL_STATIC(NetworkManager::SettingsPrivate, globalSettings)
0022 
0023 NetworkManager::SettingsPrivate::SettingsPrivate()
0024 #ifdef NMQT_STATIC
0025     : iface(NetworkManagerPrivate::DBUS_SERVICE, NetworkManagerPrivate::DBUS_SETTINGS_PATH, QDBusConnection::sessionBus())
0026 #else
0027     : iface(NetworkManagerPrivate::DBUS_SERVICE, NetworkManagerPrivate::DBUS_SETTINGS_PATH, QDBusConnection::systemBus())
0028 #endif
0029     , m_canModify(true)
0030 {
0031     QDBusConnection::systemBus().connect(NetworkManagerPrivate::DBUS_SERVICE,
0032                                          NetworkManagerPrivate::DBUS_SETTINGS_PATH,
0033                                          NetworkManagerPrivate::FDO_DBUS_PROPERTIES,
0034                                          QLatin1String("PropertiesChanged"),
0035                                          this,
0036                                          SLOT(dbusPropertiesChanged(QString, QVariantMap, QStringList)));
0037     connect(&iface, &OrgFreedesktopNetworkManagerSettingsInterface::NewConnection, this, &SettingsPrivate::onConnectionAdded);
0038     connect(&iface,
0039             &OrgFreedesktopNetworkManagerSettingsInterface::ConnectionRemoved,
0040             this,
0041             static_cast<void (SettingsPrivate::*)(const QDBusObjectPath &)>(&SettingsPrivate::onConnectionRemoved));
0042     init();
0043     // This class is a friend of NetworkManagerPrivate thus initted there too
0044     // because of the init chain we must follow,
0045     // But if this class is used first we need to make sure the
0046     // NetworkManagerPrivate also get created so we have its signals for
0047     // when the daemon dies, we just can not call it directly here or
0048     // we will have a constructor infinite loop
0049     QTimer::singleShot(0, this, SLOT(initNotifier()));
0050 }
0051 
0052 void NetworkManager::SettingsPrivate::init()
0053 {
0054     const QList<QDBusObjectPath> connectionList = iface.connections();
0055     qCDebug(NMQT) << "Connections list";
0056     for (const QDBusObjectPath &connection : connectionList) {
0057         if (!connections.contains(connection.path())) {
0058             connections.insert(connection.path(), Connection::Ptr());
0059             Q_EMIT connectionAdded(connection.path());
0060             qCDebug(NMQT) << " " << connection.path();
0061         }
0062     }
0063 
0064     // Get all Setting's properties at once
0065     QVariantMap initialProperties = NetworkManagerPrivate::retrieveInitialProperties(iface.staticInterfaceName(), NetworkManagerPrivate::DBUS_SETTINGS_PATH);
0066     if (!initialProperties.isEmpty()) {
0067         propertiesChanged(initialProperties);
0068     }
0069 }
0070 
0071 NetworkManager::Connection::List NetworkManager::SettingsPrivate::listConnections()
0072 {
0073     NetworkManager::Connection::List list;
0074     QMap<QString, Connection::Ptr>::const_iterator i = connections.constBegin();
0075     while (i != connections.constEnd()) {
0076         NetworkManager::Connection::Ptr connection = findRegisteredConnection(i.key());
0077         if (connection) {
0078             list << connection;
0079         }
0080         ++i;
0081     }
0082     return list;
0083 }
0084 
0085 NetworkManager::Connection::Ptr NetworkManager::SettingsPrivate::findConnectionByUuid(const QString &uuid)
0086 {
0087     QMap<QString, Connection::Ptr>::const_iterator i = connections.constBegin();
0088     while (i != connections.constEnd()) {
0089         NetworkManager::Connection::Ptr connection = findRegisteredConnection(i.key());
0090         if (connection && connection->uuid() == uuid) {
0091             return connection;
0092         }
0093         ++i;
0094     }
0095 
0096     return NetworkManager::Connection::Ptr();
0097 }
0098 
0099 QString NetworkManager::SettingsPrivate::hostname() const
0100 {
0101     return m_hostname;
0102 }
0103 
0104 bool NetworkManager::SettingsPrivate::canModify() const
0105 {
0106     return m_canModify;
0107 }
0108 
0109 QDBusPendingReply<QDBusObjectPath> NetworkManager::SettingsPrivate::addConnection(const NMVariantMapMap &connection)
0110 {
0111     return iface.AddConnection(connection);
0112 }
0113 
0114 QDBusPendingReply<QDBusObjectPath> NetworkManager::SettingsPrivate::addConnectionUnsaved(const NMVariantMapMap &connection)
0115 {
0116     return iface.AddConnectionUnsaved(connection);
0117 }
0118 
0119 QDBusPendingReply<bool, QStringList> NetworkManager::SettingsPrivate::loadConnections(const QStringList &filenames)
0120 {
0121     return iface.LoadConnections(filenames);
0122 }
0123 
0124 QDBusPendingReply<bool> NetworkManager::SettingsPrivate::reloadConnections()
0125 {
0126     return iface.ReloadConnections();
0127 }
0128 
0129 void NetworkManager::SettingsPrivate::initNotifier()
0130 {
0131     notifier();
0132 }
0133 
0134 void NetworkManager::SettingsPrivate::saveHostname(const QString &hostname)
0135 {
0136     iface.SaveHostname(hostname);
0137 }
0138 
0139 void NetworkManager::SettingsPrivate::dbusPropertiesChanged(const QString &interfaceName,
0140                                                             const QVariantMap &properties,
0141                                                             const QStringList &invalidatedProperties)
0142 {
0143     Q_UNUSED(invalidatedProperties);
0144     if (interfaceName == QLatin1String("org.freedesktop.NetworkManager.Settings")) {
0145         propertiesChanged(properties);
0146     }
0147 }
0148 
0149 void NetworkManager::SettingsPrivate::propertiesChanged(const QVariantMap &properties)
0150 {
0151     QVariantMap::const_iterator it = properties.constBegin();
0152     while (it != properties.constEnd()) {
0153         const QString property = it.key();
0154         if (property == QLatin1String("CanModify")) {
0155             m_canModify = it->toBool();
0156             Q_EMIT canModifyChanged(m_canModify);
0157         } else if (property == QLatin1String("Hostname")) {
0158             m_hostname = it->toString();
0159             Q_EMIT hostnameChanged(m_hostname);
0160         } else if (property == QLatin1String("Connections")) {
0161             // will never get here in runtime NM < 0.9.10
0162             // TODO some action??
0163         } else {
0164             qCWarning(NMQT) << Q_FUNC_INFO << "Unhandled property" << property;
0165         }
0166         ++it;
0167     }
0168 }
0169 
0170 void NetworkManager::SettingsPrivate::onConnectionAdded(const QDBusObjectPath &path)
0171 {
0172     const QString id = path.path();
0173     if (connections.contains(id)) {
0174         return;
0175     }
0176     connections.insert(id, Connection::Ptr());
0177     Q_EMIT connectionAdded(id);
0178 }
0179 
0180 NetworkManager::Connection::Ptr NetworkManager::SettingsPrivate::findRegisteredConnection(const QString &path)
0181 {
0182     Connection::Ptr ret;
0183     if (!path.isEmpty()) {
0184         bool contains = connections.contains(path);
0185         if (contains && connections.value(path)) {
0186             ret = connections.value(path);
0187         } else {
0188             ret = Connection::Ptr(new Connection(path), &QObject::deleteLater);
0189             connections[path] = ret;
0190             connect(ret.data(), SIGNAL(removed(QString)), this, SLOT(onConnectionRemoved(QString)));
0191             if (!contains) {
0192                 Q_EMIT connectionAdded(path);
0193             }
0194         }
0195     }
0196     return ret;
0197 }
0198 
0199 void NetworkManager::SettingsPrivate::onConnectionRemoved(const QDBusObjectPath &path)
0200 {
0201     onConnectionRemoved(path.path());
0202 }
0203 
0204 void NetworkManager::SettingsPrivate::onConnectionRemoved(const QString &path)
0205 {
0206     connections.remove(path);
0207     Q_EMIT connectionRemoved(path);
0208 }
0209 
0210 void NetworkManager::SettingsPrivate::daemonUnregistered()
0211 {
0212     connections.clear();
0213 }
0214 
0215 NetworkManager::Connection::List NetworkManager::listConnections()
0216 {
0217     return globalSettings->listConnections();
0218 }
0219 
0220 NetworkManager::Connection::Ptr NetworkManager::findConnectionByUuid(const QString &uuid)
0221 {
0222     return globalSettings->findConnectionByUuid(uuid);
0223 }
0224 
0225 NetworkManager::Connection::Ptr NetworkManager::findConnection(const QString &path)
0226 {
0227     return globalSettings->findRegisteredConnection(path);
0228 }
0229 
0230 QDBusPendingReply<QDBusObjectPath> NetworkManager::addConnection(const NMVariantMapMap &connection)
0231 {
0232     return globalSettings->addConnection(connection);
0233 }
0234 
0235 QDBusPendingReply<QDBusObjectPath> NetworkManager::addConnectionUnsaved(const NMVariantMapMap &connection)
0236 {
0237     return globalSettings->addConnectionUnsaved(connection);
0238 }
0239 
0240 QDBusPendingReply<bool, QStringList> NetworkManager::loadConnections(const QStringList &filenames)
0241 {
0242     return globalSettings->loadConnections(filenames);
0243 }
0244 
0245 QDBusPendingReply<bool> NetworkManager::reloadConnections()
0246 {
0247     return globalSettings->reloadConnections();
0248 }
0249 
0250 void NetworkManager::saveHostname(const QString &hostname)
0251 {
0252     globalSettings->saveHostname(hostname);
0253 }
0254 
0255 bool NetworkManager::canModify()
0256 {
0257     return globalSettings->canModify();
0258 }
0259 
0260 QString NetworkManager::hostname()
0261 {
0262     return globalSettings->hostname();
0263 }
0264 
0265 NetworkManager::SettingsNotifier *NetworkManager::settingsNotifier()
0266 {
0267     return globalSettings;
0268 }
0269 
0270 #include "moc_settings.cpp"
0271 #include "moc_settings_p.cpp"