QNI: transportMedium support for iOS
It can only differentiate between cellular and not cellular and then we can determine if it's disconnected or (presumably) using wifi. It is also explicitly not supported on macOS, which adds to the confusion. Task-number: QTBUG-91023 Change-Id: I1d002ba06dd9acf1a0daabfb2a4193c07871e9b4 Reviewed-by: Timur Pocheptsov <timur.pocheptsov@qt.io> Reviewed-by: Edward Welbourne <edward.welbourne@qt.io> Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
This commit is contained in:
parent
f40e0bcf67
commit
a6947853ee
@ -124,6 +124,9 @@ public:
|
||||
void updateState(SCNetworkReachabilityFlags newState);
|
||||
void reset();
|
||||
bool isReachable() const;
|
||||
#ifdef QT_PLATFORM_UIKIT
|
||||
bool isWwan() const;
|
||||
#endif
|
||||
|
||||
static void probeCallback(SCNetworkReachabilityRef probe, SCNetworkReachabilityFlags flags, void *info);
|
||||
|
||||
@ -139,9 +142,19 @@ void QNetworkConnectionMonitorPrivate::updateState(SCNetworkReachabilityFlags ne
|
||||
// is set. There are more possible flags that require more tests/some special
|
||||
// setup. So in future this part and related can change/be extended.
|
||||
const bool wasReachable = isReachable();
|
||||
|
||||
#ifdef QT_PLATFORM_UIKIT
|
||||
const bool hadWwan = isWwan();
|
||||
#endif
|
||||
|
||||
state = newState;
|
||||
if (wasReachable != isReachable())
|
||||
emit q->reachabilityChanged(isReachable());
|
||||
|
||||
#ifdef QT_PLATFORM_UIKIT
|
||||
if (hadWwan != isWwan())
|
||||
emit q->isWwanChanged(isWwan());
|
||||
#endif
|
||||
}
|
||||
|
||||
void QNetworkConnectionMonitorPrivate::reset()
|
||||
@ -160,6 +173,13 @@ bool QNetworkConnectionMonitorPrivate::isReachable() const
|
||||
return !!(state & kSCNetworkReachabilityFlagsReachable);
|
||||
}
|
||||
|
||||
#ifdef QT_PLATFORM_UIKIT // The IsWWAN flag is not available on macOS
|
||||
bool QNetworkConnectionMonitorPrivate::isWwan() const
|
||||
{
|
||||
return !!(state & kSCNetworkReachabilityFlagsIsWWAN);
|
||||
}
|
||||
#endif
|
||||
|
||||
void QNetworkConnectionMonitorPrivate::probeCallback(SCNetworkReachabilityRef probe, SCNetworkReachabilityFlags flags, void *info)
|
||||
{
|
||||
// To be executed only on the reachability queue.
|
||||
@ -301,6 +321,25 @@ bool QNetworkConnectionMonitor::isReachable()
|
||||
return d->isReachable();
|
||||
}
|
||||
|
||||
#ifdef QT_PLATFORM_UIKIT
|
||||
bool QNetworkConnectionMonitor::isWwan() const
|
||||
{
|
||||
Q_D(const QNetworkConnectionMonitor);
|
||||
|
||||
if (isMonitoring()) {
|
||||
qCWarning(lcNetMon, "Calling isReachable() is unsafe after the monitoring started");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!d->probe) {
|
||||
qCWarning(lcNetMon, "Reachability is unknown, set the target first");
|
||||
return false;
|
||||
}
|
||||
|
||||
return d->isWwan();
|
||||
}
|
||||
#endif
|
||||
|
||||
bool QNetworkConnectionMonitor::isEnabled()
|
||||
{
|
||||
return true;
|
||||
|
@ -73,7 +73,11 @@ public:
|
||||
bool setTargets(const QHostAddress &local, const QHostAddress &remote);
|
||||
bool isReachable();
|
||||
|
||||
// Important: on Darwin you should not call isReachable() after
|
||||
#ifdef QT_PLATFORM_UIKIT
|
||||
bool isWwan() const;
|
||||
#endif
|
||||
|
||||
// Important: on Darwin you should not call isReachable/isWwan() after
|
||||
// startMonitoring(), you have to listen to reachabilityChanged()
|
||||
// signal instead.
|
||||
bool startMonitoring();
|
||||
@ -87,6 +91,10 @@ Q_SIGNALS:
|
||||
// callback is coming on a special dispatch queue.
|
||||
void reachabilityChanged(bool isOnline);
|
||||
|
||||
#ifdef QT_PLATFORM_UIKIT
|
||||
void isWwanChanged(bool isWwan);
|
||||
#endif
|
||||
|
||||
private:
|
||||
Q_DECLARE_PRIVATE(QNetworkConnectionMonitor)
|
||||
Q_DISABLE_COPY_MOVE(QNetworkConnectionMonitor)
|
||||
|
@ -69,12 +69,20 @@ public:
|
||||
|
||||
static QNetworkInformation::Features featuresSupportedStatic()
|
||||
{
|
||||
return QNetworkInformation::Features(QNetworkInformation::Feature::Reachability);
|
||||
return QNetworkInformation::Features(QNetworkInformation::Feature::Reachability
|
||||
#ifdef QT_PLATFORM_UIKIT
|
||||
| QNetworkInformation::Feature::TransportMedium
|
||||
#endif
|
||||
);
|
||||
}
|
||||
|
||||
private Q_SLOTS:
|
||||
void reachabilityChanged(bool isOnline);
|
||||
|
||||
#ifdef QT_PLATFORM_UIKIT
|
||||
void isWwanChanged(bool isOnline);
|
||||
#endif
|
||||
|
||||
private:
|
||||
Q_DISABLE_COPY_MOVE(QSCNetworkReachabilityNetworkInformationBackend);
|
||||
|
||||
@ -110,10 +118,16 @@ private:
|
||||
QSCNetworkReachabilityNetworkInformationBackend::QSCNetworkReachabilityNetworkInformationBackend()
|
||||
{
|
||||
bool isOnline = false;
|
||||
#ifdef QT_PLATFORM_UIKIT
|
||||
bool isWwan = false;
|
||||
#endif
|
||||
if (ipv4Probe.setTargets(QHostAddress::AnyIPv4, {})) {
|
||||
// We manage to create SCNetworkReachabilityRef for IPv4, let's
|
||||
// read the last known state then!
|
||||
isOnline |= ipv4Probe.isReachable();
|
||||
#ifdef QT_PLATFORM_UIKIT
|
||||
isWwan |= ipv4Probe.isWwan();
|
||||
#endif
|
||||
ipv4Probe.startMonitoring();
|
||||
}
|
||||
|
||||
@ -121,9 +135,15 @@ QSCNetworkReachabilityNetworkInformationBackend::QSCNetworkReachabilityNetworkIn
|
||||
// We manage to create SCNetworkReachability ref for IPv6, let's
|
||||
// read the last known state then!
|
||||
isOnline |= ipv6Probe.isReachable();
|
||||
#ifdef QT_PLATFORM_UIKIT
|
||||
isWwan |= ipv6Probe.isWwan();
|
||||
#endif
|
||||
ipv6Probe.startMonitoring();
|
||||
}
|
||||
reachabilityChanged(isOnline);
|
||||
#ifdef QT_PLATFORM_UIKIT
|
||||
isWwanChanged(isWwan);
|
||||
#endif
|
||||
|
||||
connect(&ipv4Probe, &QNetworkConnectionMonitor::reachabilityChanged, this,
|
||||
&QSCNetworkReachabilityNetworkInformationBackend::reachabilityChanged,
|
||||
@ -131,6 +151,15 @@ QSCNetworkReachabilityNetworkInformationBackend::QSCNetworkReachabilityNetworkIn
|
||||
connect(&ipv6Probe, &QNetworkConnectionMonitor::reachabilityChanged, this,
|
||||
&QSCNetworkReachabilityNetworkInformationBackend::reachabilityChanged,
|
||||
Qt::QueuedConnection);
|
||||
|
||||
#ifdef QT_PLATFORM_UIKIT
|
||||
connect(&ipv4Probe, &QNetworkConnectionMonitor::isWwanChanged, this,
|
||||
&QSCNetworkReachabilityNetworkInformationBackend::isWwanChanged,
|
||||
Qt::QueuedConnection);
|
||||
connect(&ipv6Probe, &QNetworkConnectionMonitor::isWwanChanged, this,
|
||||
&QSCNetworkReachabilityNetworkInformationBackend::isWwanChanged,
|
||||
Qt::QueuedConnection);
|
||||
#endif
|
||||
}
|
||||
|
||||
QSCNetworkReachabilityNetworkInformationBackend::~QSCNetworkReachabilityNetworkInformationBackend()
|
||||
@ -143,6 +172,23 @@ void QSCNetworkReachabilityNetworkInformationBackend::reachabilityChanged(bool i
|
||||
: QNetworkInformation::Reachability::Disconnected);
|
||||
}
|
||||
|
||||
#ifdef QT_PLATFORM_UIKIT
|
||||
void QSCNetworkReachabilityNetworkInformationBackend::isWwanChanged(bool isWwan)
|
||||
{
|
||||
// The reachability API from Apple only has one entry regarding transport medium: "IsWWAN"[0].
|
||||
// This is _serviceable_ on iOS where the only other credible options are "WLAN" or
|
||||
// "Disconnected". But on macOS you could be connected by Ethernet as well, so how would that be
|
||||
// reported? It doesn't matter anyway since "IsWWAN" is not available on macOS.
|
||||
// [0]: https://developer.apple.com/documentation/systemconfiguration/scnetworkreachabilityflags/kscnetworkreachabilityflagsiswwan?language=objc
|
||||
if (reachability() == QNetworkInformation::Reachability::Disconnected) {
|
||||
setTransportMedium(QNetworkInformation::TransportMedium::Unknown);
|
||||
} else {
|
||||
setTransportMedium(isWwan ? QNetworkInformation::TransportMedium::Cellular
|
||||
: QNetworkInformation::TransportMedium::WiFi);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#include "qscnetworkreachabilitynetworkinformationbackend.moc"
|
||||
|
Loading…
x
Reference in New Issue
Block a user