Skip to content

Commit c936fb9

Browse files
committed
feat: add NMActiveConnectionAdapter
1 parent 840e6ec commit c936fb9

12 files changed

+263
-58
lines changed

src/network/CMakeLists.txt

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,13 +40,23 @@ qt_add_dbus_interface(NM_DBUS_INTERFACES
4040
)
4141

4242
set_source_files_properties(nm/org.freedesktop.NetworkManager.Settings.Connection.xml PROPERTIES
43-
CLASSNAME DBusNMConnectionProxy
43+
CLASSNAME DBusNMConnectionSettingsProxy
4444
INCLUDE ${CMAKE_CURRENT_SOURCE_DIR}/nm/dbus_types.hpp
4545
)
4646

4747
qt_add_dbus_interface(NM_DBUS_INTERFACES
4848
nm/org.freedesktop.NetworkManager.Settings.Connection.xml
49-
nm/dbus_nm_connection
49+
nm/dbus_nm_connection_settings
50+
)
51+
52+
set_source_files_properties(nm/org.freedesktop.NetworkManager.Connection.Active.xml PROPERTIES
53+
CLASSNAME DBusNMActiveConnectionProxy
54+
NO_NAMESPACE TRUE
55+
)
56+
57+
qt_add_dbus_interface(NM_DBUS_INTERFACES
58+
nm/org.freedesktop.NetworkManager.Connection.Active.xml
59+
nm/dbus_nm_active_connection
5060
)
5161

5262
qt_add_library(quickshell-network STATIC

src/network/nm/connection.cpp

Lines changed: 55 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,11 @@ Q_LOGGING_CATEGORY(logNetworkManager, "quickshell.network.networkmanager", QtWar
1919

2020
// NMConnectionAdapter
2121

22-
NMConnectionAdapter::NMConnectionAdapter(const QString& path, QObject* parent): QObject(parent) {
22+
NMConnectionSettingsAdapter::NMConnectionSettingsAdapter(const QString& path, QObject* parent)
23+
: QObject(parent) {
2324
qDBusRegisterMetaType<ConnectionSettingsMap>();
2425

25-
this->proxy = new DBusNMConnectionProxy(
26+
this->proxy = new DBusNMConnectionSettingsProxy(
2627
"org.freedesktop.NetworkManager",
2728
path,
2829
QDBusConnection::systemBus(),
@@ -35,16 +36,16 @@ NMConnectionAdapter::NMConnectionAdapter(const QString& path, QObject* parent):
3536
}
3637

3738
// clang-format off
38-
QObject::connect(this->proxy, &DBusNMConnectionProxy::Updated, this, &NMConnectionAdapter::updateSettings);
39+
QObject::connect(this->proxy, &DBusNMConnectionSettingsProxy::Updated, this, &NMConnectionSettingsAdapter::updateSettings);
3940
// clang-format on
4041

41-
this->connectionProperties.setInterface(this->proxy);
42-
this->connectionProperties.updateAllViaGetAll();
42+
this->connectionSettingsProperties.setInterface(this->proxy);
43+
this->connectionSettingsProperties.updateAllViaGetAll();
4344

4445
this->updateSettings();
4546
}
4647

47-
void NMConnectionAdapter::updateSettings() {
48+
void NMConnectionSettingsAdapter::updateSettings() {
4849
auto pending = this->proxy->GetSettings();
4950
auto* call = new QDBusPendingCallWatcher(pending, this);
5051

@@ -64,10 +65,55 @@ void NMConnectionAdapter::updateSettings() {
6465
QObject::connect(call, &QDBusPendingCallWatcher::finished, this, responseCallback);
6566
}
6667

67-
bool NMConnectionAdapter::isValid() const { return this->proxy && this->proxy->isValid(); }
68-
QString NMConnectionAdapter::address() const {
68+
bool NMConnectionSettingsAdapter::isValid() const { return this->proxy && this->proxy->isValid(); }
69+
QString NMConnectionSettingsAdapter::address() const {
6970
return this->proxy ? this->proxy->service() : QString();
7071
}
71-
QString NMConnectionAdapter::path() const { return this->proxy ? this->proxy->path() : QString(); }
72+
QString NMConnectionSettingsAdapter::path() const {
73+
return this->proxy ? this->proxy->path() : QString();
74+
}
75+
76+
NMActiveConnectionAdapter::NMActiveConnectionAdapter(const QString& path, QObject* parent)
77+
: QObject(parent) {
78+
79+
this->proxy = new DBusNMActiveConnectionProxy(
80+
"org.freedesktop.NetworkManager",
81+
path,
82+
QDBusConnection::systemBus(),
83+
this
84+
);
85+
86+
if (!this->proxy->isValid()) {
87+
qCWarning(logNetworkManager) << "Cannot create DBus interface for connection at" << path;
88+
return;
89+
}
90+
91+
// clang-format off
92+
QObject::connect(&this->activeConnectionProperties, &DBusPropertyGroup::getAllFinished, this, [this]() { emit this->ready(); }, Qt::SingleShotConnection);
93+
QObject::connect(this->proxy, &DBusNMActiveConnectionProxy::StateChanged, this, &NMActiveConnectionAdapter::onStateChanged);
94+
// clang-format on
95+
96+
this->activeConnectionProperties.setInterface(this->proxy);
97+
this->activeConnectionProperties.updateAllViaGetAll();
98+
}
99+
100+
void NMActiveConnectionAdapter::onStateChanged(quint32 state, quint32 reason) {
101+
auto enumState = static_cast<NMActiveConnectionState::Enum>(state);
102+
auto enumReason = static_cast<NMActiveConnectionStateReason::Enum>(reason);
103+
104+
if (enumState != mState) {
105+
this->mState = enumState;
106+
this->mStateReason = enumReason;
107+
emit this->stateChanged(enumState, enumReason);
108+
}
109+
}
110+
111+
bool NMActiveConnectionAdapter::isValid() const { return this->proxy && this->proxy->isValid(); }
112+
QString NMActiveConnectionAdapter::address() const {
113+
return this->proxy ? this->proxy->service() : QString();
114+
}
115+
QString NMActiveConnectionAdapter::path() const {
116+
return this->proxy ? this->proxy->path() : QString();
117+
}
72118

73119
} // namespace qs::network

src/network/nm/connection.hpp

Lines changed: 48 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,16 @@
1313
#include "../../dbus/properties.hpp"
1414
#include "dbus_types.hpp"
1515
#include "enums.hpp"
16-
#include "nm/dbus_nm_connection.h"
16+
#include "nm/dbus_nm_connection_settings.h"
17+
#include "nm/dbus_nm_active_connection.h"
1718

1819
namespace qs::network {
1920

20-
class NMConnectionAdapter: public QObject {
21+
class NMConnectionSettingsAdapter: public QObject {
2122
Q_OBJECT;
2223

2324
public:
24-
explicit NMConnectionAdapter(const QString& path, QObject* parent = nullptr);
25+
explicit NMConnectionSettingsAdapter(const QString& path, QObject* parent = nullptr);
2526
void updateSettings();
2627
[[nodiscard]] bool isValid() const;
2728
[[nodiscard]] QString path() const;
@@ -34,11 +35,52 @@ class NMConnectionAdapter: public QObject {
3435

3536
private:
3637
// clang-format off
37-
Q_OBJECT_BINDABLE_PROPERTY(NMConnectionAdapter, ConnectionSettingsMap, bSettings, &NMConnectionAdapter::settingsChanged);
38+
Q_OBJECT_BINDABLE_PROPERTY(NMConnectionSettingsAdapter, ConnectionSettingsMap, bSettings, &NMConnectionSettingsAdapter::settingsChanged);
3839
// clang-format on
3940

40-
QS_DBUS_BINDABLE_PROPERTY_GROUP(NMConnectionAdapter, connectionProperties);
41-
DBusNMConnectionProxy* proxy = nullptr;
41+
QS_DBUS_BINDABLE_PROPERTY_GROUP(NMConnectionSettingsAdapter, connectionSettingsProperties);
42+
DBusNMConnectionSettingsProxy* proxy = nullptr;
43+
};
44+
45+
class NMActiveConnectionAdapter: public QObject {
46+
Q_OBJECT;
47+
48+
public:
49+
explicit NMActiveConnectionAdapter(const QString& path, QObject* parent = nullptr);
50+
[[nodiscard]] bool isValid() const;
51+
[[nodiscard]] QString path() const;
52+
[[nodiscard]] QString address() const;
53+
[[nodiscard]] QDBusObjectPath connection() const { return this->bConnection; };
54+
[[nodiscard]] bool isDefault() const { return this->bIsDefault; };
55+
[[nodiscard]] bool isDefault6() const { return this->bIsDefault6; };
56+
[[nodiscard]] NMActiveConnectionState::Enum state() const { return this->mState; };
57+
[[nodiscard]] NMActiveConnectionStateReason::Enum stateReason() const { return this->mStateReason; };
58+
59+
signals:
60+
void stateChanged(NMActiveConnectionState::Enum state, NMActiveConnectionStateReason::Enum reason);
61+
void connectionChanged(QDBusObjectPath path);
62+
void isDefaultChanged(bool isDefault);
63+
void isDefault6Changed(bool isDefault6);
64+
void ready();
65+
66+
private slots:
67+
void onStateChanged(quint32 state, quint32 reason);
68+
69+
private:
70+
// clang-format off
71+
Q_OBJECT_BINDABLE_PROPERTY(NMActiveConnectionAdapter, QDBusObjectPath, bConnection, &NMActiveConnectionAdapter::connectionChanged);
72+
Q_OBJECT_BINDABLE_PROPERTY(NMActiveConnectionAdapter, bool, bIsDefault, &NMActiveConnectionAdapter::isDefaultChanged);
73+
Q_OBJECT_BINDABLE_PROPERTY(NMActiveConnectionAdapter, bool, bIsDefault6, &NMActiveConnectionAdapter::isDefault6Changed);
74+
// clang-format on
75+
76+
QS_DBUS_BINDABLE_PROPERTY_GROUP(NMActiveConnectionAdapter, activeConnectionProperties);
77+
QS_DBUS_PROPERTY_BINDING(NMActiveConnectionAdapter, pConnection, bConnection, activeConnectionProperties, "Connection");
78+
QS_DBUS_PROPERTY_BINDING(NMActiveConnectionAdapter, pIsDefault, bIsDefault, activeConnectionProperties, "Default");
79+
QS_DBUS_PROPERTY_BINDING(NMActiveConnectionAdapter, pIsDefault6, bIsDefault6, activeConnectionProperties, "Default6");
80+
DBusNMActiveConnectionProxy* proxy = nullptr;
81+
82+
NMActiveConnectionState::Enum mState = NMActiveConnectionState::Unknown;
83+
NMActiveConnectionStateReason::Enum mStateReason = NMActiveConnectionStateReason::Unknown;
4284
};
4385

4486
} // namespace qs::network

src/network/nm/device.cpp

Lines changed: 52 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -46,13 +46,44 @@ NMDeviceAdapter::NMDeviceAdapter(const QString& path, QObject* parent): QObject(
4646

4747
// clang-format off
4848
QObject::connect(this, &NMDeviceAdapter::availableConnectionsChanged, this, &NMDeviceAdapter::onAvailableConnectionsChanged);
49+
QObject::connect(this, &NMDeviceAdapter::activeConnectionChanged, this, &NMDeviceAdapter::onActiveConnectionChanged);
4950
QObject::connect(&this->deviceProperties, &DBusPropertyGroup::getAllFinished, this, [this]() { emit this->ready(); }, Qt::SingleShotConnection);
5051
// clang-format on
5152

5253
this->deviceProperties.setInterface(this->proxy);
5354
this->deviceProperties.updateAllViaGetAll();
5455
}
5556

57+
void NMDeviceAdapter::onActiveConnectionChanged(const QDBusObjectPath& path) {
58+
QString stringPath = path.path();
59+
if (this->mActiveConnection) {
60+
QObject::disconnect(this->mActiveConnection, nullptr, this, nullptr);
61+
emit this->activeConnectionRemoved(this->mActiveConnection);
62+
delete this->mActiveConnection;
63+
this->mActiveConnection = nullptr;
64+
}
65+
66+
if (stringPath != "/") {
67+
auto* active = new NMActiveConnectionAdapter(stringPath, this);
68+
this->mActiveConnection = active;
69+
qCDebug(logNetworkManager) << "Registered active connection" << stringPath;
70+
71+
QObject::connect(
72+
active,
73+
&NMActiveConnectionAdapter::ready,
74+
this,
75+
[this, active]() {
76+
QString path = active->connection().path();
77+
if (!this->mConnectionMap.contains(path)) {
78+
this->registerConnection(path);
79+
}
80+
emit this->activeConnectionLoaded(active);
81+
},
82+
Qt::SingleShotConnection
83+
);
84+
}
85+
}
86+
5687
void NMDeviceAdapter::onAvailableConnectionsChanged(const QList<QDBusObjectPath>& paths) {
5788
QSet<QString> newConnectionPaths;
5889
for (const QDBusObjectPath& path: paths) {
@@ -62,21 +93,7 @@ void NMDeviceAdapter::onAvailableConnectionsChanged(const QList<QDBusObjectPath>
6293
QSet<QString> addedConnections = newConnectionPaths - this->mConnectionPaths;
6394
QSet<QString> removedConnections = this->mConnectionPaths - newConnectionPaths;
6495
for (const QString& path: addedConnections) {
65-
auto* connection = new NMConnectionAdapter(path, this);
66-
if (!connection->isValid()) {
67-
qCWarning(logNetworkManager) << "Ignoring invalid registration of" << path;
68-
delete connection;
69-
} else {
70-
this->mConnectionMap.insert(path, connection);
71-
QObject::connect(
72-
connection,
73-
&NMConnectionAdapter::ready,
74-
this,
75-
[this, connection]() { emit this->connectionLoaded(connection); },
76-
Qt::SingleShotConnection
77-
);
78-
qCDebug(logNetworkManager) << "Registered connection" << path;
79-
}
96+
registerConnection(path);
8097
}
8198
for (const QString& path: removedConnections) {
8299
auto* connection = this->mConnectionMap.take(path);
@@ -87,9 +104,29 @@ void NMDeviceAdapter::onAvailableConnectionsChanged(const QList<QDBusObjectPath>
87104
emit this->connectionRemoved(connection);
88105
delete connection;
89106
}
107+
this->mConnectionPaths.remove(path);
90108
};
91109
}
92110

111+
void NMDeviceAdapter::registerConnection(const QString& path) {
112+
auto* connection = new NMConnectionSettingsAdapter(path, this);
113+
if (!connection->isValid()) {
114+
qCWarning(logNetworkManager) << "Ignoring invalid registration of" << path;
115+
delete connection;
116+
} else {
117+
this->mConnectionMap.insert(path, connection);
118+
this->mConnectionPaths.insert(path);
119+
QObject::connect(
120+
connection,
121+
&NMConnectionSettingsAdapter::ready,
122+
this,
123+
[this, connection]() { emit this->connectionLoaded(connection); },
124+
Qt::SingleShotConnection
125+
);
126+
qCDebug(logNetworkManager) << "Registered connection" << path;
127+
}
128+
}
129+
93130
void NMDeviceAdapter::disconnect() { this->proxy->Disconnect(); }
94131
bool NMDeviceAdapter::isValid() const { return this->proxy && this->proxy->isValid(); }
95132
QString NMDeviceAdapter::address() const {

src/network/nm/device.hpp

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,35 +57,43 @@ public slots:
5757

5858
signals:
5959
void ready();
60-
void connectionLoaded(NMConnectionAdapter* connection);
61-
void connectionRemoved(NMConnectionAdapter* connection);
60+
void connectionLoaded(NMConnectionSettingsAdapter* connection);
61+
void connectionRemoved(NMConnectionSettingsAdapter* connection);
62+
void activeConnectionLoaded(NMActiveConnectionAdapter* connection);
63+
void activeConnectionRemoved(NMActiveConnectionAdapter* connection);
6264
void interfaceChanged(const QString& interface);
6365
void hwAddressChanged(const QString& hwAddress);
6466
void typeChanged(NMDeviceType::Enum type);
6567
void stateChanged(NMDeviceState::Enum state);
6668
void availableConnectionsChanged(QList<QDBusObjectPath> paths);
69+
void activeConnectionChanged(const QDBusObjectPath& connection);
6770

6871
private slots:
6972
void onAvailableConnectionsChanged(const QList<QDBusObjectPath>& paths);
73+
void onActiveConnectionChanged(const QDBusObjectPath& path);
7074

7175
private:
76+
void registerConnection(const QString& path);
7277
// Connection lookups
7378
QSet<QString> mConnectionPaths;
74-
QHash<QString, NMConnectionAdapter*> mConnectionMap;
79+
QHash<QString, NMConnectionSettingsAdapter*> mConnectionMap;
80+
NMActiveConnectionAdapter* mActiveConnection = nullptr;
7581

7682
// clang-format off
7783
Q_OBJECT_BINDABLE_PROPERTY(NMDeviceAdapter, QString, bInterface, &NMDeviceAdapter::interfaceChanged);
7884
Q_OBJECT_BINDABLE_PROPERTY(NMDeviceAdapter, QString, bHwAddress, &NMDeviceAdapter::hwAddressChanged);
7985
Q_OBJECT_BINDABLE_PROPERTY(NMDeviceAdapter, NMDeviceState::Enum, bState, &NMDeviceAdapter::stateChanged);
8086
Q_OBJECT_BINDABLE_PROPERTY(NMDeviceAdapter, NMDeviceType::Enum, bType, &NMDeviceAdapter::typeChanged);
8187
Q_OBJECT_BINDABLE_PROPERTY(NMDeviceAdapter, QList<QDBusObjectPath>, bAvailableConnections, &NMDeviceAdapter::availableConnectionsChanged);
88+
Q_OBJECT_BINDABLE_PROPERTY(NMDeviceAdapter, QDBusObjectPath, bActiveConnection, &NMDeviceAdapter::activeConnectionChanged);
8289

8390
QS_DBUS_BINDABLE_PROPERTY_GROUP(NMDeviceAdapter, deviceProperties);
8491
QS_DBUS_PROPERTY_BINDING(NMDeviceAdapter, pName, bInterface, deviceProperties, "Interface");
8592
QS_DBUS_PROPERTY_BINDING(NMDeviceAdapter, pAddress, bHwAddress, deviceProperties, "HwAddress");
8693
QS_DBUS_PROPERTY_BINDING(NMDeviceAdapter, pType, bType, deviceProperties, "DeviceType");
8794
QS_DBUS_PROPERTY_BINDING(NMDeviceAdapter, pState, bState, deviceProperties, "State");
8895
QS_DBUS_PROPERTY_BINDING(NMDeviceAdapter, pAvailableConnections, bAvailableConnections, deviceProperties, "AvailableConnections");
96+
QS_DBUS_PROPERTY_BINDING(NMDeviceAdapter, pActiveConnection, bActiveConnection, deviceProperties, "ActiveConnection");
8997
// clang-format on
9098

9199
DBusNMDeviceProxy* proxy = nullptr;

0 commit comments

Comments
 (0)