diff options
Diffstat (limited to 'src/plugins/networkinformation')
13 files changed, 239 insertions, 142 deletions
diff --git a/src/plugins/networkinformation/android/CMakeLists.txt b/src/plugins/networkinformation/android/CMakeLists.txt index 7980ae9d76..07d9201bbb 100644 --- a/src/plugins/networkinformation/android/CMakeLists.txt +++ b/src/plugins/networkinformation/android/CMakeLists.txt @@ -12,8 +12,10 @@ qt_internal_add_jar(Qt${QtBase_VERSION_MAJOR}AndroidNetworkInformationBackend OUTPUT_DIR "${QT_BUILD_DIR}/jar" ) +qt_path_join(destination ${INSTALL_DATADIR} "jar") + install_jar(Qt${QtBase_VERSION_MAJOR}AndroidNetworkInformationBackend - DESTINATION jar + DESTINATION ${destination} COMPONENT Devel ) @@ -27,8 +29,6 @@ qt_internal_add_plugin(QAndroidNetworkInformationPlugin wrapper/androidconnectivitymanager.cpp wrapper/androidconnectivitymanager.h LIBRARIES Qt::NetworkPrivate - DEFINES - QT_USE_QSTRINGBUILDER ) set_property( diff --git a/src/plugins/networkinformation/android/jar/build.gradle b/src/plugins/networkinformation/android/jar/build.gradle index c947852f79..ea6d06c257 100644 --- a/src/plugins/networkinformation/android/jar/build.gradle +++ b/src/plugins/networkinformation/android/jar/build.gradle @@ -7,7 +7,7 @@ buildscript { } dependencies { - classpath 'com.android.tools.build:gradle:7.0.2' + classpath 'com.android.tools.build:gradle:8.4.0' } } @@ -23,12 +23,10 @@ repositories { } android { - compileSdkVersion 31 - buildToolsVersion "31.0.3" + compileSdk 34 defaultConfig { - minSdkVersion 23 - targetSdkVersion 31 + minSdkVersion 28 } sourceSets { diff --git a/src/plugins/networkinformation/android/wrapper/androidconnectivitymanager.cpp b/src/plugins/networkinformation/android/wrapper/androidconnectivitymanager.cpp index 203772971b..3c9f952968 100644 --- a/src/plugins/networkinformation/android/wrapper/androidconnectivitymanager.cpp +++ b/src/plugins/networkinformation/android/wrapper/androidconnectivitymanager.cpp @@ -48,7 +48,7 @@ static void transportMediumChanged(JNIEnv *env, jobject obj, jint enumValue) } Q_DECLARE_JNI_NATIVE_METHOD(transportMediumChanged) -Q_DECLARE_JNI_TYPE(ConnectivityManager, "Landroid/net/ConnectivityManager;") +Q_DECLARE_JNI_CLASS(ConnectivityManager, "android/net/ConnectivityManager") AndroidConnectivityManager::AndroidConnectivityManager() { @@ -93,3 +93,5 @@ bool AndroidConnectivityManager::registerNatives() const } QT_END_NAMESPACE + +#include "moc_androidconnectivitymanager.cpp" diff --git a/src/plugins/networkinformation/glib/qglibnetworkinformationbackend.cpp b/src/plugins/networkinformation/glib/qglibnetworkinformationbackend.cpp index 10ce5dbc60..0b45eb9ce3 100644 --- a/src/plugins/networkinformation/glib/qglibnetworkinformationbackend.cpp +++ b/src/plugins/networkinformation/glib/qglibnetworkinformationbackend.cpp @@ -51,7 +51,8 @@ public: static QNetworkInformation::Features featuresSupportedStatic() { using Feature = QNetworkInformation::Feature; - return QNetworkInformation::Features(Feature::Reachability | Feature::CaptivePortal); + return QNetworkInformation::Features(Feature::Reachability | Feature::CaptivePortal + | Feature::Metered); } bool isValid() const; @@ -59,10 +60,12 @@ public: private: Q_DISABLE_COPY_MOVE(QGlibNetworkInformationBackend) - static void updateInformation(QGlibNetworkInformationBackend *backend); + static void updateConnectivity(QGlibNetworkInformationBackend *backend); + static void updateMetered(QGlibNetworkInformationBackend *backend); GNetworkMonitor *networkMonitor = nullptr; - gulong handlerId = 0; + gulong connectivityHandlerId = 0; + gulong meteredHandlerId = 0; }; class QGlibNetworkInformationBackendFactory : public QNetworkInformationBackendFactory @@ -95,23 +98,28 @@ private: QGlibNetworkInformationBackend::QGlibNetworkInformationBackend() : networkMonitor(g_network_monitor_get_default()) { - updateInformation(this); + updateConnectivity(this); + updateMetered(this); - handlerId = g_signal_connect_swapped(networkMonitor, "notify::connectivity", - G_CALLBACK(updateInformation), this); + connectivityHandlerId = g_signal_connect_swapped(networkMonitor, "notify::connectivity", + G_CALLBACK(updateConnectivity), this); + + meteredHandlerId = g_signal_connect_swapped(networkMonitor, "notify::network-metered", + G_CALLBACK(updateMetered), this); } QGlibNetworkInformationBackend::~QGlibNetworkInformationBackend() { - g_signal_handler_disconnect(networkMonitor, handlerId); + g_signal_handler_disconnect(networkMonitor, meteredHandlerId); + g_signal_handler_disconnect(networkMonitor, connectivityHandlerId); } bool QGlibNetworkInformationBackend::isValid() const { - return G_OBJECT_TYPE_NAME(networkMonitor) != "GNetworkMonitorBase"_L1; + return QLatin1StringView(G_OBJECT_TYPE_NAME(networkMonitor)) != "GNetworkMonitorBase"_L1; } -void QGlibNetworkInformationBackend::updateInformation(QGlibNetworkInformationBackend *backend) +void QGlibNetworkInformationBackend::updateConnectivity(QGlibNetworkInformationBackend *backend) { const auto connectivityState = g_network_monitor_get_connectivity(backend->networkMonitor); const bool behindPortal = (connectivityState == G_NETWORK_CONNECTIVITY_PORTAL); @@ -119,6 +127,11 @@ void QGlibNetworkInformationBackend::updateInformation(QGlibNetworkInformationBa backend->setBehindCaptivePortal(behindPortal); } +void QGlibNetworkInformationBackend::updateMetered(QGlibNetworkInformationBackend *backend) +{ + backend->setMetered(g_network_monitor_get_network_metered(backend->networkMonitor)); +} + QT_END_NAMESPACE #include "qglibnetworkinformationbackend.moc" diff --git a/src/plugins/networkinformation/networklistmanager/CMakeLists.txt b/src/plugins/networkinformation/networklistmanager/CMakeLists.txt index 77501d0e5c..acd3754f4e 100644 --- a/src/plugins/networkinformation/networklistmanager/CMakeLists.txt +++ b/src/plugins/networkinformation/networklistmanager/CMakeLists.txt @@ -14,9 +14,10 @@ qt_internal_add_plugin(QNLMNIPlugin Qt::NetworkPrivate ) -qt_internal_extend_target(QNLMNIPlugin CONDITION WIN32 AND MSVC AND NOT CLANG +qt_internal_extend_target(QNLMNIPlugin CONDITION WIN32 LIBRARIES runtimeobject + oleaut32 ) # Don't repeat the target name in AUTOGEN_BUILD_DIR to work around issues with overlong paths. diff --git a/src/plugins/networkinformation/networklistmanager/qnetworklistmanagerevents.cpp b/src/plugins/networkinformation/networklistmanager/qnetworklistmanagerevents.cpp index f46dfb88ee..caa5046751 100644 --- a/src/plugins/networkinformation/networklistmanager/qnetworklistmanagerevents.cpp +++ b/src/plugins/networkinformation/networklistmanager/qnetworklistmanagerevents.cpp @@ -9,15 +9,7 @@ #include <mutex> #if QT_CONFIG(cpp_winrt) -#include <winrt/base.h> -#include <QtCore/private/qfactorycacheregistration_p.h> -// Workaround for Windows SDK bug. -// See https://github.com/microsoft/Windows.UI.Composition-Win32-Samples/issues/47 -namespace winrt::impl -{ - template <typename Async> - auto wait_for(Async const& async, Windows::Foundation::TimeSpan const& timeout); -} +#include <QtCore/private/qt_winrtbase_p.h> #include <winrt/Windows.Networking.Connectivity.h> #endif // QT_CONFIG(cpp_winrt) @@ -110,16 +102,22 @@ bool QNetworkListManagerEvents::start() #if QT_CONFIG(cpp_winrt) using namespace winrt::Windows::Networking::Connectivity; using winrt::Windows::Foundation::IInspectable; - // Register for changes in the network and store a token to unregister later: - token = NetworkInformation::NetworkStatusChanged( - [owner = QPointer(this)](const IInspectable sender) { - Q_UNUSED(sender); - if (owner) { - std::scoped_lock locker(owner->winrtLock); - if (owner->token) - owner->emitWinRTUpdates(); - } - }); + try { + // Register for changes in the network and store a token to unregister later: + token = NetworkInformation::NetworkStatusChanged( + [owner = QPointer(this)](const IInspectable sender) { + Q_UNUSED(sender); + if (owner) { + std::scoped_lock locker(owner->winrtLock); + if (owner->token) + owner->emitWinRTUpdates(); + } + }); + } catch (const winrt::hresult_error &ex) { + qCWarning(lcNetInfoNLM) << "Failed to register network status changed callback:" + << QSystemError::windowsComString(ex.code()); + } + // Emit initial state emitWinRTUpdates(); #endif @@ -205,7 +203,9 @@ QNetworkInformation::TransportMedium getTransportMedium(const ConnectionProfile NetworkAdapter adapter(nullptr); try { adapter = profile.NetworkAdapter(); - } catch (...) { + } catch (const winrt::hresult_error &ex) { + qCWarning(lcNetInfoNLM) << "Failed to obtain network adapter:" + << QSystemError::windowsComString(ex.code()); // pass, we will return Unknown anyway } if (adapter == nullptr) @@ -233,7 +233,9 @@ QNetworkInformation::TransportMedium getTransportMedium(const ConnectionProfile ConnectionCost cost(nullptr); try { cost = profile.GetConnectionCost(); - } catch (...) { + } catch (const winrt::hresult_error &ex) { + qCWarning(lcNetInfoNLM) << "Failed to obtain connection cost:" + << QSystemError::windowsComString(ex.code()); // pass, we return false if we get an empty object back anyway } if (cost == nullptr) @@ -249,7 +251,9 @@ void QNetworkListManagerEvents::emitWinRTUpdates() ConnectionProfile profile = nullptr; try { profile = NetworkInformation::GetInternetConnectionProfile(); - } catch (...) { + } catch (const winrt::hresult_error &ex) { + qCWarning(lcNetInfoNLM) << "Failed to obtain connection profile:" + << QSystemError::windowsComString(ex.code()); // pass, we would just return early if we get an empty object back anyway } if (profile == nullptr) @@ -260,3 +264,5 @@ void QNetworkListManagerEvents::emitWinRTUpdates() #endif // QT_CONFIG(cpp_winrt) QT_END_NAMESPACE + +#include "moc_qnetworklistmanagerevents.cpp" diff --git a/src/plugins/networkinformation/networklistmanager/qnetworklistmanagerevents.h b/src/plugins/networkinformation/networklistmanager/qnetworklistmanagerevents.h index 43a3252c49..d91cd8a4cc 100644 --- a/src/plugins/networkinformation/networklistmanager/qnetworklistmanagerevents.h +++ b/src/plugins/networkinformation/networklistmanager/qnetworklistmanagerevents.h @@ -1,6 +1,9 @@ // Copyright (C) 2021 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +#ifndef QNETWORKLISTMANAGEREVENTS_H +#define QNETWORKLISTMANAGEREVENTS_H + #include <QtNetwork/private/qtnetworkglobal_p.h> #include <QtNetwork/qnetworkinformation.h> @@ -17,8 +20,7 @@ #include <wrl/wrappers/corewrappers.h> #if QT_CONFIG(cpp_winrt) -#include <winrt/base.h> -#include <QtCore/private/qfactorycacheregistration_p.h> +#include <QtCore/private/qt_winrtbase_p.h> #endif using namespace Microsoft::WRL; @@ -73,3 +75,5 @@ private: }; QT_END_NAMESPACE + +#endif // QNETWORKLISTMANAGEREVENTS_H diff --git a/src/plugins/networkinformation/networklistmanager/qnetworklistmanagernetworkinformationbackend.cpp b/src/plugins/networkinformation/networklistmanager/qnetworklistmanagernetworkinformationbackend.cpp index a5b0179e37..766648486e 100644 --- a/src/plugins/networkinformation/networklistmanager/qnetworklistmanagernetworkinformationbackend.cpp +++ b/src/plugins/networkinformation/networklistmanager/qnetworklistmanagernetworkinformationbackend.cpp @@ -72,6 +72,7 @@ public: | QNetworkInformation::Feature::CaptivePortal #if QT_CONFIG(cpp_winrt) | QNetworkInformation::Feature::TransportMedium + | QNetworkInformation::Feature::Metered #endif ); } diff --git a/src/plugins/networkinformation/networkmanager/CMakeLists.txt b/src/plugins/networkinformation/networkmanager/CMakeLists.txt index e98ea84e3a..9d76dbe7b4 100644 --- a/src/plugins/networkinformation/networkmanager/CMakeLists.txt +++ b/src/plugins/networkinformation/networkmanager/CMakeLists.txt @@ -7,6 +7,7 @@ qt_internal_add_plugin(QNetworkManagerNetworkInformationPlugin PLUGIN_TYPE networkinformation DEFAULT_IF LINUX SOURCES + qnetworkmanagernetworkinformationbackend.h qnetworkmanagernetworkinformationbackend.cpp qnetworkmanagerservice.h qnetworkmanagerservice.cpp diff --git a/src/plugins/networkinformation/networkmanager/qnetworkmanagernetworkinformationbackend.cpp b/src/plugins/networkinformation/networkmanager/qnetworkmanagernetworkinformationbackend.cpp index 6ee84e06f8..f583d1dcf6 100644 --- a/src/plugins/networkinformation/networkmanager/qnetworkmanagernetworkinformationbackend.cpp +++ b/src/plugins/networkinformation/networkmanager/qnetworkmanagernetworkinformationbackend.cpp @@ -1,9 +1,7 @@ // Copyright (C) 2021 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only -#include <QtNetwork/private/qnetworkinformation_p.h> - -#include "qnetworkmanagerservice.h" +#include "qnetworkmanagernetworkinformationbackend.h" #include <QtCore/qglobal.h> #include <QtCore/private/qobject_p.h> @@ -100,39 +98,14 @@ bool isMeteredFromNMMetered(QNetworkManagerInterface::NMMetered metered) static QString backendName() { - return QString::fromUtf16(QNetworkInformationBackend::PluginNames - [QNetworkInformationBackend::PluginNamesLinuxIndex]); + return QStringView(QNetworkInformationBackend::PluginNames + [QNetworkInformationBackend::PluginNamesLinuxIndex]).toString(); } -class QNetworkManagerNetworkInformationBackend : public QNetworkInformationBackend +QString QNetworkManagerNetworkInformationBackend::name() const { - Q_OBJECT -public: - QNetworkManagerNetworkInformationBackend(); - ~QNetworkManagerNetworkInformationBackend() = default; - - QString name() const override { return backendName(); } - QNetworkInformation::Features featuresSupported() const override - { - if (!isValid()) - return {}; - return featuresSupportedStatic(); - } - - static QNetworkInformation::Features featuresSupportedStatic() - { - using Feature = QNetworkInformation::Feature; - return QNetworkInformation::Features(Feature::Reachability | Feature::CaptivePortal - | Feature::TransportMedium | Feature::Metered); - } - - bool isValid() const { return iface.isValid(); } - -private: - Q_DISABLE_COPY_MOVE(QNetworkManagerNetworkInformationBackend) - - QNetworkManagerInterface iface; -}; + return backendName(); +} class QNetworkManagerNetworkInformationBackendFactory : public QNetworkInformationBackendFactory { @@ -167,34 +140,42 @@ private: QNetworkManagerNetworkInformationBackend::QNetworkManagerNetworkInformationBackend() { - auto updateReachability = [this](QNetworkManagerInterface::NMState newState) { - setReachability(reachabilityFromNMState(newState)); - }; - updateReachability(iface.state()); - connect(&iface, &QNetworkManagerInterface::stateChanged, this, std::move(updateReachability)); - - auto updateBehindCaptivePortal = [this](QNetworkManagerInterface::NMConnectivityState state) { - const bool behindPortal = (state == QNetworkManagerInterface::NM_CONNECTIVITY_PORTAL); - setBehindCaptivePortal(behindPortal); - }; - updateBehindCaptivePortal(iface.connectivityState()); - connect(&iface, &QNetworkManagerInterface::connectivityChanged, this, - std::move(updateBehindCaptivePortal)); - - auto updateTransportMedium = [this](QNetworkManagerInterface::NMDeviceType newDevice) { - setTransportMedium(transportMediumFromDeviceType(newDevice)); - }; - updateTransportMedium(iface.deviceType()); - connect(&iface, &QNetworkManagerInterface::deviceTypeChanged, this, - std::move(updateTransportMedium)); - - auto updateMetered = [this](QNetworkManagerInterface::NMMetered metered) { - setMetered(isMeteredFromNMMetered(metered)); - }; - updateMetered(iface.meteredState()); - connect(&iface, &QNetworkManagerInterface::meteredChanged, this, std::move(updateMetered)); + if (!iface.isValid()) + return; + iface.setBackend(this); + onStateChanged(iface.state()); + onConnectivityChanged(iface.connectivityState()); + onDeviceTypeChanged(iface.deviceType()); + onMeteredChanged(iface.meteredState()); +} + +void QNetworkManagerNetworkInformationBackend::onStateChanged( + QNetworkManagerInterface::NMState newState) +{ + setReachability(reachabilityFromNMState(newState)); } +void QNetworkManagerNetworkInformationBackend::onConnectivityChanged( + QNetworkManagerInterface::NMConnectivityState connectivityState) +{ + const bool behindPortal = + (connectivityState == QNetworkManagerInterface::NM_CONNECTIVITY_PORTAL); + setBehindCaptivePortal(behindPortal); +} + +void QNetworkManagerNetworkInformationBackend::onDeviceTypeChanged( + QNetworkManagerInterface::NMDeviceType newDevice) +{ + setTransportMedium(transportMediumFromDeviceType(newDevice)); +} + +void QNetworkManagerNetworkInformationBackend::onMeteredChanged( + QNetworkManagerInterface::NMMetered metered) +{ + setMetered(isMeteredFromNMMetered(metered)); +}; + QT_END_NAMESPACE #include "qnetworkmanagernetworkinformationbackend.moc" +#include "moc_qnetworkmanagernetworkinformationbackend.cpp" diff --git a/src/plugins/networkinformation/networkmanager/qnetworkmanagernetworkinformationbackend.h b/src/plugins/networkinformation/networkmanager/qnetworkmanagernetworkinformationbackend.h new file mode 100644 index 0000000000..3b60f0949c --- /dev/null +++ b/src/plugins/networkinformation/networkmanager/qnetworkmanagernetworkinformationbackend.h @@ -0,0 +1,60 @@ +// Copyright (C) 2021 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +#ifndef QNETWORKMANAGERINFORMATIONBACKEND_H +#define QNETWORKMANAGERINFORMATIONBACKEND_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtNetwork/private/qnetworkinformation_p.h> +#include "qnetworkmanagerservice.h" + +QT_BEGIN_NAMESPACE + +class QNetworkManagerNetworkInformationBackend : public QNetworkInformationBackend +{ + Q_OBJECT +public: + QNetworkManagerNetworkInformationBackend(); + ~QNetworkManagerNetworkInformationBackend() = default; + + QString name() const override; + QNetworkInformation::Features featuresSupported() const override + { + if (!isValid()) + return {}; + return featuresSupportedStatic(); + } + + static QNetworkInformation::Features featuresSupportedStatic() + { + using Feature = QNetworkInformation::Feature; + return QNetworkInformation::Features(Feature::Reachability | Feature::CaptivePortal + | Feature::TransportMedium | Feature::Metered); + } + + bool isValid() const { return iface.isValid(); } + + void onStateChanged(QNetworkManagerInterface::NMState state); + void onConnectivityChanged(QNetworkManagerInterface::NMConnectivityState connectivityState); + void onDeviceTypeChanged(QNetworkManagerInterface::NMDeviceType deviceType); + void onMeteredChanged(QNetworkManagerInterface::NMMetered metered); + +private: + Q_DISABLE_COPY_MOVE(QNetworkManagerNetworkInformationBackend) + + QNetworkManagerInterface iface; +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/plugins/networkinformation/networkmanager/qnetworkmanagerservice.cpp b/src/plugins/networkinformation/networkmanager/qnetworkmanagerservice.cpp index 3a64c1892c..c055555cac 100644 --- a/src/plugins/networkinformation/networkmanager/qnetworkmanagerservice.cpp +++ b/src/plugins/networkinformation/networkmanager/qnetworkmanagerservice.cpp @@ -2,6 +2,7 @@ // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #include "qnetworkmanagerservice.h" +#include "qnetworkmanagernetworkinformationbackend.h" #include <QObject> #include <QList> @@ -14,21 +15,40 @@ #include <QtDBus/QDBusObjectPath> #include <QtDBus/QDBusPendingCall> -#define DBUS_PROPERTIES_INTERFACE "org.freedesktop.DBus.Properties" +#define DBUS_PROPERTIES_INTERFACE "org.freedesktop.DBus.Properties"_L1 -#define NM_DBUS_SERVICE "org.freedesktop.NetworkManager" +#define NM_DBUS_INTERFACE "org.freedesktop.NetworkManager" +#define NM_DBUS_SERVICE NM_DBUS_INTERFACE ""_L1 -#define NM_DBUS_PATH "/org/freedesktop/NetworkManager" -#define NM_DBUS_INTERFACE NM_DBUS_SERVICE -#define NM_CONNECTION_DBUS_INTERFACE NM_DBUS_SERVICE ".Connection.Active" -#define NM_DEVICE_DBUS_INTERFACE NM_DBUS_SERVICE ".Device" +#define NM_DBUS_PATH "/org/freedesktop/NetworkManager"_L1 +#define NM_CONNECTION_DBUS_INTERFACE NM_DBUS_SERVICE ".Connection.Active"_L1 +#define NM_DEVICE_DBUS_INTERFACE NM_DBUS_SERVICE ".Device"_L1 QT_BEGIN_NAMESPACE using namespace Qt::StringLiterals; +namespace { +constexpr QLatin1StringView propertiesChangedKey = "PropertiesChanged"_L1; +const QString &stateKey() +{ + static auto key = u"State"_s; + return key; +} +const QString &connectivityKey() +{ + static auto key = u"Connectivity"_s; + return key; +} +const QString &primaryConnectionKey() +{ + static auto key = u"PrimaryConnection"_s; + return key; +} +} + QNetworkManagerInterfaceBase::QNetworkManagerInterfaceBase(QObject *parent) - : QDBusAbstractInterface(NM_DBUS_SERVICE ""_L1, NM_DBUS_PATH ""_L1, + : QDBusAbstractInterface(NM_DBUS_SERVICE, NM_DBUS_PATH, NM_DBUS_INTERFACE, QDBusConnection::systemBus(), parent) { } @@ -41,45 +61,49 @@ bool QNetworkManagerInterfaceBase::networkManagerAvailable() QNetworkManagerInterface::QNetworkManagerInterface(QObject *parent) : QNetworkManagerInterfaceBase(parent) { - if (!isValid()) + if (!QDBusAbstractInterface::isValid()) return; PropertiesDBusInterface managerPropertiesInterface( - NM_DBUS_SERVICE ""_L1, NM_DBUS_PATH ""_L1, DBUS_PROPERTIES_INTERFACE, + NM_DBUS_SERVICE, NM_DBUS_PATH, DBUS_PROPERTIES_INTERFACE, QDBusConnection::systemBus()); QList<QVariant> argumentList; - argumentList << NM_DBUS_INTERFACE ""_L1; + argumentList << NM_DBUS_SERVICE; QDBusPendingReply<QVariantMap> propsReply = managerPropertiesInterface.callWithArgumentList( QDBus::Block, "GetAll"_L1, argumentList); - if (!propsReply.isError()) { - propertyMap = propsReply.value(); - } else { - qWarning() << "propsReply" << propsReply.error().message(); + if (propsReply.isError()) { + validDBusConnection = false; + if (auto error = propsReply.error(); error.type() != QDBusError::AccessDenied) + qWarning() << "Failed to query NetworkManager properties:" << error.message(); + return; } + propertyMap = propsReply.value(); - QDBusConnection::systemBus().connect(NM_DBUS_SERVICE ""_L1, NM_DBUS_PATH ""_L1, - DBUS_PROPERTIES_INTERFACE""_L1, "PropertiesChanged"_L1, this, - SLOT(setProperties(QString, QMap<QString, QVariant>, QList<QString>))); + validDBusConnection = QDBusConnection::systemBus().connect(NM_DBUS_SERVICE, NM_DBUS_PATH, + DBUS_PROPERTIES_INTERFACE, propertiesChangedKey, this, + SLOT(setProperties(QString,QMap<QString,QVariant>,QList<QString>))); } QNetworkManagerInterface::~QNetworkManagerInterface() { - QDBusConnection::systemBus().disconnect(NM_DBUS_SERVICE ""_L1, NM_DBUS_PATH ""_L1, - DBUS_PROPERTIES_INTERFACE ""_L1, "PropertiesChanged"_L1, this, - SLOT(setProperties(QString, QMap<QString, QVariant>, QList<QString>))); + QDBusConnection::systemBus().disconnect(NM_DBUS_SERVICE, NM_DBUS_PATH, + DBUS_PROPERTIES_INTERFACE, propertiesChangedKey, this, + SLOT(setProperties(QString,QMap<QString,QVariant>,QList<QString>))); } QNetworkManagerInterface::NMState QNetworkManagerInterface::state() const { - if (propertyMap.contains("State")) - return static_cast<QNetworkManagerInterface::NMState>(propertyMap.value("State").toUInt()); + auto it = propertyMap.constFind(stateKey()); + if (it != propertyMap.cend()) + return static_cast<QNetworkManagerInterface::NMState>(it->toUInt()); return QNetworkManagerInterface::NM_STATE_UNKNOWN; } QNetworkManagerInterface::NMConnectivityState QNetworkManagerInterface::connectivityState() const { - if (propertyMap.contains("Connectivity")) - return static_cast<NMConnectivityState>(propertyMap.value("Connectivity").toUInt()); + auto it = propertyMap.constFind(connectivityKey()); + if (it != propertyMap.cend()) + return static_cast<NMConnectivityState>(it->toUInt()); return QNetworkManagerInterface::NM_CONNECTIVITY_UNKNOWN; } @@ -102,7 +126,7 @@ static std::optional<QDBusInterface> getPrimaryDevice(const QDBusObjectPath &dev std::optional<QDBusObjectPath> QNetworkManagerInterface::primaryConnectionDevicePath() const { - auto it = propertyMap.constFind(u"PrimaryConnection"_s); + auto it = propertyMap.constFind(primaryConnectionKey()); if (it != propertyMap.cend()) return it->value<QDBusObjectPath>(); return std::nullopt; @@ -150,6 +174,11 @@ auto QNetworkManagerInterface::extractDeviceMetered(const QDBusObjectPath &devic return static_cast<NMMetered>(metered.toUInt()); } +void QNetworkManagerInterface::setBackend(QNetworkManagerNetworkInformationBackend *ourBackend) +{ + backend = ourBackend; +} + void QNetworkManagerInterface::setProperties(const QString &interfaceName, const QMap<QString, QVariant> &map, const QStringList &invalidatedProperties) @@ -169,18 +198,18 @@ void QNetworkManagerInterface::setProperties(const QString &interfaceName, } if (valueChanged) { - if (i.key() == "State"_L1) { + if (i.key() == stateKey()) { quint32 state = i.value().toUInt(); - Q_EMIT stateChanged(static_cast<NMState>(state)); - } else if (i.key() == "Connectivity"_L1) { + backend->onStateChanged(static_cast<NMState>(state)); + } else if (i.key() == connectivityKey()) { quint32 state = i.value().toUInt(); - Q_EMIT connectivityChanged(static_cast<NMConnectivityState>(state)); - } else if (i.key() == "PrimaryConnection"_L1) { + backend->onConnectivityChanged(static_cast<NMConnectivityState>(state)); + } else if (i.key() == primaryConnectionKey()) { const QDBusObjectPath devicePath = i->value<QDBusObjectPath>(); - Q_EMIT deviceTypeChanged(extractDeviceType(devicePath)); - Q_EMIT meteredChanged(extractDeviceMetered(devicePath)); + backend->onDeviceTypeChanged(extractDeviceType(devicePath)); + backend->onMeteredChanged(extractDeviceMetered(devicePath)); } else if (i.key() == "Metered"_L1) { - Q_EMIT meteredChanged(static_cast<NMMetered>(i->toUInt())); + backend->onMeteredChanged(static_cast<NMMetered>(i->toUInt())); } } } diff --git a/src/plugins/networkinformation/networkmanager/qnetworkmanagerservice.h b/src/plugins/networkinformation/networkmanager/qnetworkmanagerservice.h index 9ca862d398..5201e8485b 100644 --- a/src/plugins/networkinformation/networkmanager/qnetworkmanagerservice.h +++ b/src/plugins/networkinformation/networkmanager/qnetworkmanagerservice.h @@ -39,6 +39,7 @@ enum NMDeviceState { QT_BEGIN_NAMESPACE class QDBusObjectPath; +class QNetworkManagerNetworkInformationBackend; // This tiny class exists for the purpose of seeing if NetworkManager is available without // initializing everything the derived/full class needs. @@ -46,7 +47,7 @@ class QNetworkManagerInterfaceBase : public QDBusAbstractInterface { Q_OBJECT public: - QNetworkManagerInterfaceBase(QObject *parent = nullptr); + explicit QNetworkManagerInterfaceBase(QObject *parent = nullptr); ~QNetworkManagerInterfaceBase() = default; static bool networkManagerAvailable(); @@ -128,19 +129,17 @@ public: NM_METERED_GUESS_NO, }; - QNetworkManagerInterface(QObject *parent = nullptr); + explicit QNetworkManagerInterface(QObject *parent = nullptr); ~QNetworkManagerInterface(); + void setBackend(QNetworkManagerNetworkInformationBackend *ourBackend); + 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); + bool isValid() const { return QDBusAbstractInterface::isValid() && validDBusConnection; } private Q_SLOTS: void setProperties(const QString &interfaceName, const QMap<QString, QVariant> &map, @@ -155,6 +154,8 @@ private: std::optional<QDBusObjectPath> primaryConnectionDevicePath() const; QVariantMap propertyMap; + QNetworkManagerNetworkInformationBackend *backend = nullptr; + bool validDBusConnection = true; }; class PropertiesDBusInterface : public QDBusAbstractInterface |