diff options
author | Mårten Nordheim <marten.nordheim@qt.io> | 2021-10-25 20:23:24 +0200 |
---|---|---|
committer | Mårten Nordheim <marten.nordheim@qt.io> | 2021-11-04 11:02:40 +0000 |
commit | 33df48f957eafef356f0a6912c6541feada1db98 (patch) | |
tree | 7cb50dc02c57347d0fd340d016e52b402aa0fa33 /src/plugins/networkinformation | |
parent | 58b37f5908be86a478f20cbbe70228009bd3a481 (diff) |
QNI: networkmanager support for the isMetered API
Task-number: QTBUG-91024
Change-Id: I25ac05adbcbfa92a98fe1e9db9ac931e5c340fcd
Reviewed-by: Marc Mutz <marc.mutz@qt.io>
Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
Diffstat (limited to 'src/plugins/networkinformation')
3 files changed, 79 insertions, 15 deletions
diff --git a/src/plugins/networkinformation/networkmanager/qnetworkmanagernetworkinformationbackend.cpp b/src/plugins/networkinformation/networkmanager/qnetworkmanagernetworkinformationbackend.cpp index 5e2f4b61e6..ac16ad4b8d 100644 --- a/src/plugins/networkinformation/networkmanager/qnetworkmanagernetworkinformationbackend.cpp +++ b/src/plugins/networkinformation/networkmanager/qnetworkmanagernetworkinformationbackend.cpp @@ -118,7 +118,22 @@ transportMediumFromDeviceType(QNetworkManagerInterface::NMDeviceType type) // entries added in NetworkManager that isn't listed here return QNetworkInformation::TransportMedium::Unknown; } + +bool isMeteredFromNMMetered(QNetworkManagerInterface::NMMetered metered) +{ + switch (metered) { + case QNetworkManagerInterface::NM_METERED_YES: + case QNetworkManagerInterface::NM_METERED_GUESS_YES: + return true; + case QNetworkManagerInterface::NM_METERED_NO: + case QNetworkManagerInterface::NM_METERED_GUESS_NO: + case QNetworkManagerInterface::NM_METERED_UNKNOWN: + return false; + } + Q_UNREACHABLE(); + return false; } +} // unnamed namespace static QString backendName() { @@ -145,7 +160,7 @@ public: { using Feature = QNetworkInformation::Feature; return QNetworkInformation::Features(Feature::Reachability | Feature::CaptivePortal - | Feature::TransportMedium); + | Feature::TransportMedium | Feature::Metered); } bool isValid() const { return iface.isValid(); } @@ -215,6 +230,12 @@ QNetworkManagerNetworkInformationBackend::QNetworkManagerNetworkInformationBacke [this](NMDeviceType newDevice) { setTransportMedium(transportMediumFromDeviceType(newDevice)); }); + + auto updateMetered = [this](QNetworkManagerInterface::NMMetered metered) { + setMetered(isMeteredFromNMMetered(metered)); + }; + updateMetered(iface.meteredState()); + connect(&iface, &QNetworkManagerInterface::meteredChanged, this, std::move(updateMetered)); } QT_END_NAMESPACE diff --git a/src/plugins/networkinformation/networkmanager/qnetworkmanagerservice.cpp b/src/plugins/networkinformation/networkmanager/qnetworkmanagerservice.cpp index 82a797ab87..dfc09b4637 100644 --- a/src/plugins/networkinformation/networkmanager/qnetworkmanagerservice.cpp +++ b/src/plugins/networkinformation/networkmanager/qnetworkmanagerservice.cpp @@ -119,7 +119,23 @@ QNetworkManagerInterface::NMConnectivityState QNetworkManagerInterface::connecti return QNetworkManagerInterface::NM_CONNECTIVITY_UNKNOWN; } -QNetworkManagerInterface::NMDeviceType QNetworkManagerInterface::deviceType() const +static QDBusInterface getPrimaryDevice(const QDBusObjectPath &devicePath) +{ + const QDBusInterface connection(NM_DBUS_SERVICE, devicePath.path(), + NM_CONNECTION_DBUS_INTERFACE, QDBusConnection::systemBus()); + if (!connection.isValid()) + return QDBusInterface({}, {}); + + const auto devicePaths = connection.property("Devices").value<QList<QDBusObjectPath>>(); + if (devicePaths.isEmpty()) + return QDBusInterface({}, {}); + + const QDBusObjectPath primaryDevicePath = devicePaths.front(); + return QDBusInterface(NM_DBUS_SERVICE, primaryDevicePath.path(), NM_DEVICE_DBUS_INTERFACE, + QDBusConnection::systemBus()); +} + +auto QNetworkManagerInterface::deviceType() const -> NMDeviceType { auto it = propertyMap.constFind("PrimaryConnection"); if (it != propertyMap.cend()) @@ -127,26 +143,37 @@ QNetworkManagerInterface::NMDeviceType QNetworkManagerInterface::deviceType() co return NM_DEVICE_TYPE_UNKNOWN; } -auto QNetworkManagerInterface::extractDeviceType(QDBusObjectPath devicePath) const -> NMDeviceType +auto QNetworkManagerInterface::meteredState() const -> NMMetered { - const QDBusInterface connection(NM_DBUS_SERVICE, devicePath.path(), - NM_CONNECTION_DBUS_INTERFACE, QDBusConnection::systemBus()); - if (!connection.isValid()) - return NM_DEVICE_TYPE_UNKNOWN; + auto it = propertyMap.constFind(u"PrimaryConnection"_qs); + if (it != propertyMap.cend()) + return extractDeviceMetered(it->value<QDBusObjectPath>()); + return NM_METERED_UNKNOWN; +} - const auto devicePaths = connection.property("Devices").value<QList<QDBusObjectPath>>(); - if (devicePaths.isEmpty()) +auto QNetworkManagerInterface::extractDeviceType(QDBusObjectPath devicePath) const -> NMDeviceType +{ + QDBusInterface primaryDevice = getPrimaryDevice(devicePath); + if (!primaryDevice.isValid()) return NM_DEVICE_TYPE_UNKNOWN; - - const QDBusObjectPath primaryDevicePath = devicePaths.front(); - const QDBusInterface device(NM_DBUS_SERVICE, primaryDevicePath.path(), NM_DEVICE_DBUS_INTERFACE, - QDBusConnection::systemBus()); - const QVariant deviceType = device.property("DeviceType"); + const QVariant deviceType = primaryDevice.property("DeviceType"); if (!deviceType.isValid()) return NM_DEVICE_TYPE_UNKNOWN; return static_cast<NMDeviceType>(deviceType.toUInt()); } +auto QNetworkManagerInterface::extractDeviceMetered(const QDBusObjectPath &devicePath) const + -> NMMetered +{ + QDBusInterface primaryDevice = getPrimaryDevice(devicePath); + if (!primaryDevice.isValid()) + return NM_METERED_UNKNOWN; + const QVariant metered = primaryDevice.property("Metered"); + if (!metered.isValid()) + return NM_METERED_UNKNOWN; + return static_cast<NMMetered>(metered.toUInt()); +} + void QNetworkManagerInterface::setProperties(const QString &interfaceName, const QMap<QString, QVariant> &map, const QStringList &invalidatedProperties) @@ -173,7 +200,11 @@ void QNetworkManagerInterface::setProperties(const QString &interfaceName, quint32 state = i.value().toUInt(); Q_EMIT connectivityChanged(static_cast<NMConnectivityState>(state)); } else if (i.key() == QLatin1String("PrimaryConnection")) { - Q_EMIT deviceTypeChanged(extractDeviceType(i->value<QDBusObjectPath>())); + const QDBusObjectPath devicePath = i->value<QDBusObjectPath>(); + Q_EMIT deviceTypeChanged(extractDeviceType(devicePath)); + Q_EMIT meteredChanged(extractDeviceMetered(devicePath)); + } else if (i.key() == QLatin1String("Metered")) { + Q_EMIT meteredChanged(static_cast<NMMetered>(i->toUInt())); } } } diff --git a/src/plugins/networkinformation/networkmanager/qnetworkmanagerservice.h b/src/plugins/networkinformation/networkmanager/qnetworkmanagerservice.h index 93fa23870f..48073fd1a5 100644 --- a/src/plugins/networkinformation/networkmanager/qnetworkmanagerservice.h +++ b/src/plugins/networkinformation/networkmanager/qnetworkmanagerservice.h @@ -150,6 +150,15 @@ public: NM_DEVICE_TYPE_WIFI_P2P = 30, NM_DEVICE_TYPE_VRF = 31, }; + // Matches 'NMMetered' from + // https://developer-old.gnome.org/NetworkManager/stable/nm-dbus-types.html#NMMetered + enum NMMetered { + NM_METERED_UNKNOWN, + NM_METERED_YES, + NM_METERED_NO, + NM_METERED_GUESS_YES, + NM_METERED_GUESS_NO, + }; QNetworkManagerInterface(QObject *parent = nullptr); ~QNetworkManagerInterface(); @@ -157,11 +166,13 @@ public: NMState state() const; NMConnectivityState connectivityState() const; NMDeviceType deviceType() const; + NMMetered meteredState() const; Q_SIGNALS: void stateChanged(NMState); void connectivityChanged(NMConnectivityState); void deviceTypeChanged(NMDeviceType); + void meteredChanged(NMMetered); private Q_SLOTS: void setProperties(const QString &interfaceName, const QMap<QString, QVariant> &map, @@ -171,6 +182,7 @@ private: Q_DISABLE_COPY_MOVE(QNetworkManagerInterface) NMDeviceType extractDeviceType(QDBusObjectPath devicePath) const; + NMMetered extractDeviceMetered(const QDBusObjectPath &devicePath) const; QVariantMap propertyMap; }; |