summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMårten Nordheim <marten.nordheim@qt.io>2021-10-07 13:40:01 +0200
committerMårten Nordheim <marten.nordheim@qt.io>2021-10-20 17:16:53 +0200
commit3c5c13c639b15b97a4baf681ae124917c334bab2 (patch)
tree78fd6f813bb91b66468f1930393670642003e64e
parenta9d51298ae34ed05adb100983ed92bec07ce2ce5 (diff)
QNI: Windows: support transportMedium
Brings support for transportMedium to NetworkListManager backend. Which, with this patch, also uses winrt API because there is no equivalent API available in NLM. This API is so much nicer than NLM... Task-number: QTBUG-91023 Change-Id: I360a3a197caa2aa4848c8f768aea6a09a68b0ed5 Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Oliver Wolff <oliver.wolff@qt.io>
-rw-r--r--src/plugins/networkinformation/networklistmanager/CMakeLists.txt5
-rw-r--r--src/plugins/networkinformation/networklistmanager/qnetworklistmanagerevents.cpp72
-rw-r--r--src/plugins/networkinformation/networklistmanager/qnetworklistmanagerevents.h17
-rw-r--r--src/plugins/networkinformation/networklistmanager/qnetworklistmanagernetworkinformationbackend.cpp9
4 files changed, 102 insertions, 1 deletions
diff --git a/src/plugins/networkinformation/networklistmanager/CMakeLists.txt b/src/plugins/networkinformation/networklistmanager/CMakeLists.txt
index b5cf60b62c..d927d4af60 100644
--- a/src/plugins/networkinformation/networklistmanager/CMakeLists.txt
+++ b/src/plugins/networkinformation/networklistmanager/CMakeLists.txt
@@ -10,6 +10,11 @@ qt_internal_add_plugin(QNLMNIPlugin
Qt::NetworkPrivate
)
+qt_internal_extend_target(QNLMNIPlugin CONDITION WIN32 AND MSVC AND NOT CLANG
+ LIBRARIES
+ runtimeobject
+)
+
# Don't repeat the target name in AUTOGEN_BUILD_DIR to work around issues with overlong paths.
set_property(TARGET QNLMNIPlugin PROPERTY
AUTOGEN_BUILD_DIR "${CMAKE_CURRENT_BINARY_DIR}/autogen")
diff --git a/src/plugins/networkinformation/networklistmanager/qnetworklistmanagerevents.cpp b/src/plugins/networkinformation/networklistmanager/qnetworklistmanagerevents.cpp
index bac5c1f339..dcc1439482 100644
--- a/src/plugins/networkinformation/networklistmanager/qnetworklistmanagerevents.cpp
+++ b/src/plugins/networkinformation/networklistmanager/qnetworklistmanagerevents.cpp
@@ -39,6 +39,19 @@
#include "qnetworklistmanagerevents.h"
+#ifdef SUPPORTS_WINRT
+#include <winrt/base.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 <winrt/Windows.Networking.Connectivity.h>
+#endif
+
QT_BEGIN_NAMESPACE
namespace {
@@ -121,6 +134,19 @@ bool QNetworkListManagerEvents::start()
qCWarning(lcNetInfoNLM) << "Could not get connectivity:" << errorStringFromHResult(hr);
else
emit connectivityChanged(connectivity);
+
+#ifdef SUPPORTS_WINRT
+ using namespace winrt::Windows::Networking::Connectivity;
+ // Register for changes in the network and store a token to unregister later:
+ token = NetworkInformation::NetworkStatusChanged(
+ [this](const winrt::Windows::Foundation::IInspectable sender) {
+ Q_UNUSED(sender);
+ emit transportMediumChanged(getTransportMedium());
+ });
+ // Emit initial state
+ emit transportMediumChanged(getTransportMedium());
+#endif
+
return true;
}
@@ -134,6 +160,13 @@ bool QNetworkListManagerEvents::stop()
return false;
}
cookie = 0;
+
+#ifdef SUPPORTS_WINRT
+ using namespace winrt::Windows::Networking::Connectivity;
+ // Pass the token we stored earlier to unregister:
+ NetworkInformation::NetworkStatusChanged(token);
+ token = {};
+#endif
return true;
}
@@ -175,4 +208,43 @@ bool QNetworkListManagerEvents::checkBehindCaptivePortal()
return false;
}
+// NB: this isn't part of "network list manager", but sadly NLM doesn't have an
+// equivalent API (at least not that I've found...)!
+QNetworkInformation::TransportMedium QNetworkListManagerEvents::getTransportMedium()
+{
+#ifdef SUPPORTS_WINRT
+ using namespace winrt::Windows::Networking::Connectivity;
+ ConnectionProfile profile = NetworkInformation::GetInternetConnectionProfile();
+ if (profile == nullptr)
+ return QNetworkInformation::TransportMedium::Unknown;
+
+ if (profile.IsWwanConnectionProfile())
+ return QNetworkInformation::TransportMedium::Cellular;
+ if (profile.IsWlanConnectionProfile())
+ return QNetworkInformation::TransportMedium::WiFi;
+
+ NetworkAdapter adapter = profile.NetworkAdapter();
+ if (adapter == nullptr)
+ return QNetworkInformation::TransportMedium::Unknown;
+
+ // Note: Bluetooth is given an iana iftype of 6, which is the same as Ethernet.
+ // In Windows itself there is clearly a distinction between a Bluetooth PAN
+ // and an Ethernet LAN, though it is not clear how they make this distinction.
+ auto fromIanaId = [](quint32 ianaId) -> QNetworkInformation::TransportMedium {
+ // https://www.iana.org/assignments/ianaiftype-mib/ianaiftype-mib
+ switch (ianaId) {
+ case 6:
+ return QNetworkInformation::TransportMedium::Ethernet;
+ case 71: // Should be handled before entering this lambda
+ return QNetworkInformation::TransportMedium::WiFi;
+ }
+ return QNetworkInformation::TransportMedium::Unknown;
+ };
+
+ return fromIanaId(adapter.IanaInterfaceType());
+#else
+ return QNetworkInformation::TransportMedium::Unknown;
+#endif
+}
+
QT_END_NAMESPACE
diff --git a/src/plugins/networkinformation/networklistmanager/qnetworklistmanagerevents.h b/src/plugins/networkinformation/networklistmanager/qnetworklistmanagerevents.h
index 60a2367e4f..8618a09a84 100644
--- a/src/plugins/networkinformation/networklistmanager/qnetworklistmanagerevents.h
+++ b/src/plugins/networkinformation/networklistmanager/qnetworklistmanagerevents.h
@@ -39,6 +39,8 @@
#include <QtNetwork/private/qtnetworkglobal_p.h>
+#include <QtNetwork/qnetworkinformation.h>
+
#include <QtCore/qstring.h>
#include <QtCore/qobject.h>
#include <QtCore/qloggingcategory.h>
@@ -49,6 +51,14 @@
#include <wrl/wrappers/corewrappers.h>
#include <comdef.h>
+#if defined(Q_CC_MSVC) && !defined(Q_CC_CLANG)
+#define SUPPORTS_WINRT 1
+#endif
+
+#ifdef SUPPORTS_WINRT
+#include <winrt/base.h>
+#endif
+
using namespace Microsoft::WRL;
QT_BEGIN_NAMESPACE
@@ -88,11 +98,18 @@ public:
signals:
void connectivityChanged(NLM_CONNECTIVITY);
+ void transportMediumChanged(QNetworkInformation::TransportMedium);
private:
+ [[nodiscard]] QNetworkInformation::TransportMedium getTransportMedium();
+
ComPtr<INetworkListManager> networkListManager = nullptr;
ComPtr<IConnectionPoint> connectionPoint = nullptr;
+#ifdef SUPPORTS_WINRT
+ winrt::event_token token;
+#endif
+
QAtomicInteger<ULONG> ref = 0;
DWORD cookie = 0;
};
diff --git a/src/plugins/networkinformation/networklistmanager/qnetworklistmanagernetworkinformationbackend.cpp b/src/plugins/networkinformation/networklistmanager/qnetworklistmanagernetworkinformationbackend.cpp
index 73952b3395..e8b36be02e 100644
--- a/src/plugins/networkinformation/networklistmanager/qnetworklistmanagernetworkinformationbackend.cpp
+++ b/src/plugins/networkinformation/networklistmanager/qnetworklistmanagernetworkinformationbackend.cpp
@@ -99,7 +99,11 @@ public:
static QNetworkInformation::Features featuresSupportedStatic()
{
return QNetworkInformation::Features(QNetworkInformation::Feature::Reachability
- | QNetworkInformation::Feature::CaptivePortal);
+ | QNetworkInformation::Feature::CaptivePortal
+#ifdef SUPPORTS_WINRT
+ | QNetworkInformation::Feature::TransportMedium
+#endif
+ );
}
[[nodiscard]] bool start();
@@ -158,6 +162,9 @@ QNetworkListManagerNetworkInformationBackend::QNetworkListManagerNetworkInformat
managerEvents = new QNetworkListManagerEvents();
connect(managerEvents.Get(), &QNetworkListManagerEvents::connectivityChanged, this,
&QNetworkListManagerNetworkInformationBackend::setConnectivity);
+
+ connect(managerEvents.Get(), &QNetworkListManagerEvents::transportMediumChanged, this,
+ &QNetworkListManagerNetworkInformationBackend::setTransportMedium);
}
QNetworkListManagerNetworkInformationBackend::~QNetworkListManagerNetworkInformationBackend()